security: Porting security elements to the updated framework

Change-Id: Ie9ad6ee34f94fc520b9d3c8adf871e2557eaa9b6
diff --git a/src/security/identity/identity-manager.cpp b/src/security/identity/identity-manager.cpp
index 88e6782..ce90cc5 100644
--- a/src/security/identity/identity-manager.cpp
+++ b/src/security/identity/identity-manager.cpp
@@ -17,11 +17,12 @@
 #include <fstream>
 #include <math.h>
 #include <ndn-cpp/key-locator.hpp>
-#include <ndn-cpp/sha256-with-rsa-signature.hpp>
-#include <ndn-cpp/security/security-exception.hpp>
+
 #include "../../util/logging.hpp"
 #include "../../c/util/time.h"
 #include <ndn-cpp/security/identity/identity-manager.hpp>
+#include "../certificate/identity-certificate.hpp"
+#include "../signature/signature-sha256-with-rsa.hpp"
 
 INIT_LOGGER("ndn.security.IdentityManager")
 
@@ -29,41 +30,51 @@
 
 namespace ndn {
 
+const ptr_lib::shared_ptr<IdentityStorage>   IdentityManager::DefaultIdentityStorage   = ptr_lib::shared_ptr<IdentityStorage>();
+const ptr_lib::shared_ptr<PrivateKeyStorage> IdentityManager::DefaultPrivateKeyStorage = ptr_lib::shared_ptr<PrivateKeyStorage>();
+
+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 (!identityStorage_->doesIdentityExist(identityName)) {
-  _LOG_DEBUG("Create Identity");
-  identityStorage_->addIdentity(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 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("Create self-signed certificate");
+    ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
   
-  _LOG_DEBUG("Add self-signed certificate as default");
+    _LOG_DEBUG("Add self-signed certificate as default");
 
-  addCertificateAsDefault(*selfCert);
+    addCertificateAsDefault(*selfCert);
 
-  return keyName;
+    return keyName;
   }
   else
-    throw SecurityException("Identity has already been created!");
+    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 = identityStorage_->getNewKeyName(identityName, isKsk);
+  Name keyName = info().getNewKeyName(identityName, isKsk);
 
   _LOG_DEBUG("Generate key pair in private storage");
-  privateKeyStorage_->generateKeyPair(keyName.toUri(), keyType, keySize);
+  tpm().generateKeyPair(keyName.toUri(), keyType, keySize);
 
   _LOG_DEBUG("Create a key record in public storage");
-  ptr_lib::shared_ptr<PublicKey> pubKey = privateKeyStorage_->getPublicKey(keyName.toUri());
-  identityStorage_->addKey(keyName, keyType, pubKey->getKeyDer());
+  ptr_lib::shared_ptr<PublicKey> pubKey = tpm().getPublicKey(keyName.toUri());
+  info().addKey(keyName, keyType, *pubKey);
 
   return keyName;
 }
@@ -81,12 +92,12 @@
 {
   Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
 
-  identityStorage_->setDefaultKeyNameForIdentity(keyName, identityName);
+  info().setDefaultKeyNameForIdentity(keyName, identityName);
   
   return keyName;
 }
 
-Name
+ptr_lib::shared_ptr<IdentityCertificate>
 IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
                                            const Name& signerCertificateName,
                                            const MillisecondsSince1970& notBefore,
@@ -94,15 +105,15 @@
 {
   Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
   
-  Blob keyBlob = identityStorage_->getKey(keyName);
-  ptr_lib::shared_ptr<PublicKey> publicKey = PublicKey::fromDer(keyBlob);
+  ptr_lib::shared_ptr<IdentityCertificate> certificate =
+    createIdentityCertificate(certificatePrefix,
+                              *info().getKey(keyName),
+                              signerCertificateName,
+                              notBefore, notAfter);
 
-  ptr_lib::shared_ptr<IdentityCertificate> certificate = createIdentityCertificate
-    (certificatePrefix, *publicKey,  signerCertificateName, notBefore, notAfter);
-
-  identityStorage_->addCertificate(*certificate);
+  info().addCertificate(*certificate);
   
-  return certificate->getName();
+  return certificate;
 }
 
 ptr_lib::shared_ptr<IdentityCertificate>
@@ -112,16 +123,11 @@
                                            const MillisecondsSince1970& notBefore,
                                            const MillisecondsSince1970& notAfter)
 {
-  ptr_lib::shared_ptr<IdentityCertificate> certificate(new IdentityCertificate());
+  ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
   Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
   
   Name certificateName = certificatePrefix;
-  MillisecondsSince1970 ti = ::ndn_getNowMilliseconds();
-  // Get the number of seconds.
-  ostringstream oss;
-  oss << floor(ti / 1000.0);
-
-  certificateName.append("ID-CERT").append(oss.str());
+  certificateName.append("ID-CERT").appendVersion();
   
   certificate->setName(certificateName);
   certificate->setNotBefore(notBefore);
@@ -130,33 +136,34 @@
   certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
   certificate->encode();
 
-  ptr_lib::shared_ptr<Sha256WithRsaSignature> sha256Sig(new Sha256WithRsaSignature());
+  signByCertificate(*certificate, signerCertificateName);
 
-  KeyLocator keyLocator;    
-  keyLocator.setType(ndn_KeyLocatorType_KEYNAME);
-  keyLocator.setKeyName(signerCertificateName);
+  return certificate;
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+IdentityManager::selfSign(const Name& keyName)
+{
+  ptr_lib::shared_ptr<IdentityCertificate> certificate(new IdentityCertificate());
   
-  sha256Sig->setKeyLocator(keyLocator);
-  sha256Sig->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publicKey.getDigest());
+  Name certificateName = keyName.getSubName(0, keyName.size() - 1);
+  certificateName.append("KEY").append(keyName.get(keyName.size() - 1)).append("ID-CERT").appendVersion();
+  
+  certificate->setName(certificateName);
+  certificate->setNotBefore(ndn_getNowMilliseconds());
+  certificate->setNotAfter(ndn_getNowMilliseconds() + 630720000 /* 20 years*/);
+  certificate->setPublicKeyInfo(*info().getKey(keyName));
+  certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+  certificate->encode();
 
-  certificate->setSignature(*sha256Sig);
-
-  SignedBlob unsignedData = certificate->wireEncode();
-
-  ptr_lib::shared_ptr<IdentityCertificate> signerCertificate = getCertificate(signerCertificateName);
-  Name signerkeyName = signerCertificate->getPublicKeyName();
-
-  Blob sigBits = privateKeyStorage_->sign(unsignedData, signerkeyName);
-    
-  sha256Sig->setSignature(sigBits);
-
+  selfSign(*certificate);
   return certificate;
 }
 
 void
 IdentityManager::addCertificateAsDefault(const IdentityCertificate& certificate)
 {
-  identityStorage_->addCertificate(certificate);
+  info().addCertificate(certificate);
 
   setDefaultCertificateForKey(certificate);
 }
@@ -164,7 +171,7 @@
 void
 IdentityManager::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
 {
-  identityStorage_->addCertificate(certificate);
+  info().addCertificate(certificate);
 
   Name keyName = certificate.getPublicKeyName();
     
@@ -178,113 +185,45 @@
 {
   Name keyName = certificate.getPublicKeyName();
   
-  if(!identityStorage_->doesKeyExist(keyName))
-    throw SecurityException("No corresponding Key record for certificate!");
+  if(!info().doesKeyExist(keyName))
+    throw Error("No corresponding Key record for certificate!");
 
-  identityStorage_->setDefaultCertificateNameForKey(keyName, certificate.getName());
+  info().setDefaultCertificateNameForKey(keyName, certificate.getName());
 }
   
-ptr_lib::shared_ptr<Signature>
+Signature
 IdentityManager::signByCertificate(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
 {
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
-  ptr_lib::shared_ptr<PublicKey> publicKey = privateKeyStorage_->getPublicKey(keyName.toUri());
+  ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
 
-  Blob sigBits = privateKeyStorage_->sign(buffer, bufferLength, keyName.toUri());
-
-  //For temporary usage, we support RSA + SHA256 only, but will support more.
-  ptr_lib::shared_ptr<Sha256WithRsaSignature> sha256Sig(new Sha256WithRsaSignature());
-
-  KeyLocator keyLocator;    
-  keyLocator.setType(ndn_KeyLocatorType_KEYNAME);
-  keyLocator.setKeyName(certificateName);
-  
-  sha256Sig->setKeyLocator(keyLocator);
-  sha256Sig->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publicKey->getDigest());
-  sha256Sig->setSignature(sigBits);
-
-  return sha256Sig;
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  signature.setValue(tpm().sign(buffer, bufferLength, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+  return signature;
 }
 
 void
-IdentityManager::signByCertificate(Data &data, const Name &certificateName, WireFormat& wireFormat)
+IdentityManager::signByCertificate(Data &data, const Name &certificateName)
 {
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
-  ptr_lib::shared_ptr<PublicKey> publicKey = privateKeyStorage_->getPublicKey(keyName);
+  ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
 
   // For temporary usage, we support RSA + SHA256 only, but will support more.
-  data.setSignature(Sha256WithRsaSignature());
-  // Get a pointer to the clone which Data made.
-  Sha256WithRsaSignature *signature = dynamic_cast<Sha256WithRsaSignature*>(data.getSignature());
-  DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256;
-    
-  signature->getKeyLocator().setType(ndn_KeyLocatorType_KEYNAME);
-  signature->getKeyLocator().setKeyName(certificateName.getPrefix(-1));
-  // Omit the certificate digest.
-  signature->getKeyLocator().setKeyNameType((ndn_KeyNameType)-1);
-  // Ignore witness and leave the digestAlgorithm as the default.
-  signature->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publicKey->getDigest());
-  
-  // Encode once to get the signed portion.
-  SignedBlob encoding = data.wireEncode(wireFormat);
-  
-  signature->setSignature
-    (privateKeyStorage_->sign(encoding.signedBuf(), encoding.signedSize(), keyName, digestAlgorithm));
-
-  // Encode again to include the signature.
-  data.wireEncode(wireFormat);
+  signature.setValue(tpm().sign(data, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+  data.setSignature(signature);
 }
 
-ptr_lib::shared_ptr<IdentityCertificate>
-IdentityManager::selfSign(const Name& keyName)
+void
+IdentityManager::selfSign (IdentityCertificate& cert)
 {
-  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").append("0");
-  certificate->setName(certificateName);
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(cert.getName().getPrefix(cert.getName().size()-1)); // implicit conversion should take care
 
-  Blob keyBlob = identityStorage_->getKey(keyName);
-  ptr_lib::shared_ptr<PublicKey> publicKey = PublicKey::fromDer(keyBlob);
-
-#if NDN_CPP_HAVE_GMTIME_SUPPORT
-  time_t nowSeconds = time(NULL);
-  struct tm current = *gmtime(&nowSeconds);
-  current.tm_hour = 0;
-  current.tm_min  = 0;
-  current.tm_sec  = 0;
-  MillisecondsSince1970 notBefore = timegm(&current) * 1000.0;
-  current.tm_year = current.tm_year + 20;
-  MillisecondsSince1970 notAfter = timegm(&current) * 1000.0;
-
-  certificate->setNotBefore(notBefore);
-  certificate->setNotAfter(notAfter);
-#else
-  // Don't really expect this to happen.
-  throw SecurityException("selfSign: Can't set certificate validity because time functions are not supported by the standard library.");
-#endif  
-  certificate->setPublicKeyInfo(*publicKey);
-  certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
-  certificate->encode();
-
-  ptr_lib::shared_ptr<Sha256WithRsaSignature> sha256Sig(new Sha256WithRsaSignature());
-
-  KeyLocator keyLocator;    
-  keyLocator.setType(ndn_KeyLocatorType_KEYNAME);
-  keyLocator.setKeyName(certificateName);
-  
-  sha256Sig->setKeyLocator(keyLocator);
-  sha256Sig->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publicKey->getDigest());
-
-  certificate->setSignature(*sha256Sig);
-
-  Blob unsignedData = certificate->wireEncode();
-
-  Blob sigBits = privateKeyStorage_->sign(unsignedData, keyName.toUri());
-  
-  sha256Sig->setSignature(sigBits);
-
-  return certificate;
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  signature.setValue(tpm().sign(cert, signature, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+  cert.setSignature(signature);
 }
 
 Name
@@ -300,7 +239,7 @@
   }
     
   if (i >= certificatePrefix.size())
-    throw SecurityException("Identity Certificate Prefix does not have a KEY component");
+    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));