security: fixing bugs and adding methods

1. changing getCertificate to take only one argument, now validation checking is always enforced.
2. changing KSK-... DSK-... to lower case ksk-..., dsk-...
3. adding a addCertificateAsSystemDefault method to facilitate setting default certificate of the system.
4. using static_cast<int> (rather than floor) to round time.
5. sanity checking for key name in SecPublicInfo and SecPublicInfoSqlite3.

Change-Id: Id67af9873efef3df92458ed7a87623f22167c558
diff --git a/include/ndn-cpp/security/identity/sec-public-info-memory.hpp b/include/ndn-cpp/security/identity/sec-public-info-memory.hpp
index 734d4d7..c991f1a 100644
--- a/include/ndn-cpp/security/identity/sec-public-info-memory.hpp
+++ b/include/ndn-cpp/security/identity/sec-public-info-memory.hpp
@@ -112,7 +112,7 @@
    * @return The requested certificate.  If not found, return a shared_ptr with a null pointer.
    */
   virtual ptr_lib::shared_ptr<IdentityCertificate> 
-  getCertificate(const Name &certificateName, bool allowAny = false);
+  getCertificate(const Name &certificateName);
 
 
   /*****************************************
diff --git a/include/ndn-cpp/security/identity/sec-public-info-sqlite3.hpp b/include/ndn-cpp/security/identity/sec-public-info-sqlite3.hpp
index 335b724..99dac54 100644
--- a/include/ndn-cpp/security/identity/sec-public-info-sqlite3.hpp
+++ b/include/ndn-cpp/security/identity/sec-public-info-sqlite3.hpp
@@ -127,7 +127,7 @@
    * @return The requested certificate.  If not found, return a shared_ptr with a null pointer.
    */
   virtual ptr_lib::shared_ptr<IdentityCertificate> 
-  getCertificate(const Name &certificateName, bool allowAny);
+  getCertificate(const Name &certificateName);
 
 
   /*****************************************
diff --git a/include/ndn-cpp/security/identity/sec-public-info.hpp b/include/ndn-cpp/security/identity/sec-public-info.hpp
index 3a46310..961cf95 100644
--- a/include/ndn-cpp/security/identity/sec-public-info.hpp
+++ b/include/ndn-cpp/security/identity/sec-public-info.hpp
@@ -14,6 +14,7 @@
 #include "../certificate/public-key.hpp"
 #include "../certificate/identity-certificate.hpp"
 
+
 namespace ndn {
 
 /**
@@ -114,7 +115,7 @@
    * @return The requested certificate.  If not found, return a shared_ptr with a null pointer.
    */
   virtual ptr_lib::shared_ptr<IdentityCertificate> 
-  getCertificate(const Name &certificateName, bool allowAny = false) = 0;
+  getCertificate(const Name &certificateName) = 0;
 
 
   /*****************************************
@@ -254,6 +255,9 @@
   inline void
   addCertificateAsIdentityDefault(const IdentityCertificate& certificate);
 
+  inline void
+  addCertificateAsSystemDefault(const IdentityCertificate& certificate);
+
   inline ptr_lib::shared_ptr<IdentityCertificate>
   defaultCertificate();
   
@@ -295,19 +299,16 @@
 Name
 SecPublicInfo::getNewKeyName (const Name& identityName, bool useKsk)
 {
-  MillisecondsSince1970 ti = getNow();
-  // Get the number of seconds.
   std::ostringstream oss;
-  oss << floor(ti / 1000.0);  
 
-  std::string keyIdStr;
-    
   if (useKsk)
-    keyIdStr = ("KSK-" + oss.str());
+    oss << "ksk-";
   else
-    keyIdStr = ("DSK-" + oss.str());
+    oss << "dsk-";
 
-  Name keyName = Name(identityName).append(keyIdStr);
+  oss << static_cast<int>(getNow()/1000);  
+
+  Name keyName = Name(identityName).append(oss.str());
 
   if (doesPublicKeyExist(keyName))
     throw Error("Key name already exists");
@@ -339,8 +340,21 @@
 SecPublicInfo::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
 {
   addCertificate(certificate);
-  setDefaultKeyNameForIdentityInternal(certificate.getPublicKeyName());
-  setDefaultCertificateNameForKeyInternal(certificate.getName());
+  Name certName = certificate.getName();
+  setDefaultKeyNameForIdentityInternal(IdentityCertificate::certificateNameToPublicKeyName(certName));
+  setDefaultCertificateNameForKeyInternal(certName);
+  refreshDefaultCertificate();
+}
+
+void
+SecPublicInfo::addCertificateAsSystemDefault(const IdentityCertificate& certificate)
+{
+  addCertificate(certificate);
+  Name certName = certificate.getName();
+  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certName);
+  setDefaultIdentityInternal(keyName.getPrefix(-1));
+  setDefaultKeyNameForIdentityInternal(keyName);
+  setDefaultCertificateNameForKeyInternal(certName);
   refreshDefaultCertificate();
 }
 
@@ -353,7 +367,11 @@
 void
 SecPublicInfo::refreshDefaultCertificate()
 {
-  defaultCertificate_ = getCertificate(getDefaultCertificateNameForIdentity(getDefaultIdentity()));
+  Name certName = getDefaultCertificateNameForIdentity(getDefaultIdentity());
+  if(certName.empty())
+    defaultCertificate_.reset();
+  else
+    defaultCertificate_ = getCertificate(certName);
 }
 
 
diff --git a/src/c/util/time.c b/src/c/util/time.c
index 4c3be3a..29c20c6 100644
--- a/src/c/util/time.c
+++ b/src/c/util/time.c
@@ -43,7 +43,7 @@
     // Don't expect this to happen.
     fraction = ".000000";
     
-  time_t seconds = (time_t)floor(secondsSince1970);
+  time_t seconds = (time_t)secondsSince1970;
   struct tm* gmt = gmtime(&seconds);
   sprintf(isoString, "%04d%02d%02dT%02d%02d%02d%s", 1900 + gmt->tm_year, gmt->tm_mon + 1, gmt->tm_mday,
     gmt->tm_hour, gmt->tm_min, gmt->tm_sec, fraction);
diff --git a/src/security/certificate/identity-certificate.cpp b/src/security/certificate/identity-certificate.cpp
index aa2ad9c..1deb46f 100644
--- a/src/security/certificate/identity-certificate.cpp
+++ b/src/security/certificate/identity-certificate.cpp
@@ -59,17 +59,31 @@
 {
   int i = certificateName.size() - 1;
   string idString("ID-CERT");
+  bool foundIdString = false;
   for (; i >= 0; i--) {
     if (certificateName.get(i).toEscapedString() == idString)
-      break;
+      {
+        foundIdString = true;
+        break;
+      }
   }
+
+  if(!foundIdString)
+    throw Error("Incorrect identity certificate name " + certificateName.toUri());
     
   Name tmpName = certificateName.getSubName(0, i);    
   string keyString("KEY");
+  bool foundKeyString = false;
   for (i = 0; i < tmpName.size(); i++) {
     if (tmpName.get(i).toEscapedString() == keyString)
-      break;
+      {
+        foundKeyString = true;
+        break;
+      }
   }
+
+  if(!foundKeyString)
+    throw Error("Incorrect identity certificate name " + certificateName.toUri());
   
   return tmpName.getSubName(0, i).append(tmpName.getSubName(i + 1, tmpName.size() - i - 1));
 }
diff --git a/src/security/identity/sec-public-info-memory.cpp b/src/security/identity/sec-public-info-memory.cpp
index 3336547..966e574 100644
--- a/src/security/identity/sec-public-info-memory.cpp
+++ b/src/security/identity/sec-public-info-memory.cpp
@@ -119,7 +119,7 @@
 }
 
 ptr_lib::shared_ptr<IdentityCertificate> 
-SecPublicInfoMemory::getCertificate(const Name& certificateName, bool allowAny)
+SecPublicInfoMemory::getCertificate(const Name& certificateName)
 {
   CertificateStore::iterator record = certificateStore_.find(certificateName.toUri());
   if (record == certificateStore_.end())
diff --git a/src/security/identity/sec-public-info-sqlite3.cpp b/src/security/identity/sec-public-info-sqlite3.cpp
index 78ea986..8f80db9 100644
--- a/src/security/identity/sec-public-info-sqlite3.cpp
+++ b/src/security/identity/sec-public-info-sqlite3.cpp
@@ -222,6 +222,9 @@
 bool 
 SecPublicInfoSqlite3::doesPublicKeyExist(const Name& keyName)
 {
+  if(keyName.empty())
+    throw Error("Incorrect key name " + keyName.toUri());
+
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
 
@@ -248,6 +251,9 @@
 void
 SecPublicInfoSqlite3::addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
 {
+  if(keyName.empty())
+    throw Error("Incorrect key name " + keyName.toUri());
+
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
 
@@ -302,6 +308,9 @@
 void 
 SecPublicInfoSqlite3::updateKeyStatus(const Name& keyName, bool isActive)
 {
+  if(keyName.empty())
+    throw Error("Incorrect key name " + keyName.toUri());
+
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
   
@@ -343,7 +352,10 @@
 SecPublicInfoSqlite3::addAnyCertificate(const IdentityCertificate& certificate)
 {
   std::string certificateName = certificate.getName().toUri();
-  Name keyName = certificate.getPublicKeyName();
+  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
+
+  if(keyName.empty())
+    throw Error("Incorrect key name " + keyName.toUri());
 
   std::string keyId = keyName.get(-1).toEscapedString();
   std::string identityName = keyName.getPrefix(-1).toUri();
@@ -382,7 +394,7 @@
 SecPublicInfoSqlite3::addCertificate(const IdentityCertificate& certificate)
 {
   const Name& certificateName = certificate.getName();
-  Name keyName = certificate.getPublicKeyName();
+  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
 
   if (!doesPublicKeyExist(keyName))
     throw Error("No corresponding Key record for certificate!" + keyName.toUri() + " " + certificateName.toUri());
@@ -421,8 +433,8 @@
   sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
 
   // Convert from milliseconds to seconds since 1/1/1970.
-  sqlite3_bind_int64(statement, 5, (sqlite3_int64)floor(certificate.getNotBefore() / 1000.0));
-  sqlite3_bind_int64(statement, 6, (sqlite3_int64)floor(certificate.getNotAfter() / 1000.0));
+  sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
+  sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
 
   sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_TRANSIENT);
 
@@ -432,24 +444,17 @@
 }
 
 ptr_lib::shared_ptr<IdentityCertificate> 
-SecPublicInfoSqlite3::getCertificate(const Name &certificateName, bool allowAny)
+SecPublicInfoSqlite3::getCertificate(const Name &certificateName)
 {
   if (doesCertificateExist(certificateName)) {
     sqlite3_stmt *statement;
-    if (!allowAny) {
-      sqlite3_prepare_v2(database_, 
-                          "SELECT certificate_data FROM Certificate \
-                           WHERE cert_name=? AND not_before<datetime('now') AND not_after>datetime('now') and valid_flag=1",
-                          -1, &statement, 0);
-          
-      sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
-    }
-    else {
-      sqlite3_prepare_v2(database_, 
-                          "SELECT certificate_data FROM Certificate WHERE cert_name=?", -1, &statement, 0);
 
-      sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
-    }
+    sqlite3_prepare_v2(database_, 
+                       "SELECT certificate_data FROM Certificate \
+                        WHERE cert_name=? AND not_before<datetime('now') AND not_after>datetime('now') and valid_flag=1",
+                       -1, &statement, 0);
+          
+    sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
       
     int res = sqlite3_step(statement);
       
@@ -532,6 +537,9 @@
 void 
 SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal(const Name& keyName)
 {
+  if(keyName.empty())
+    throw Error("Incorrect key name " + keyName.toUri());
+
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
 
@@ -561,6 +569,9 @@
 Name 
 SecPublicInfoSqlite3::getDefaultCertificateNameForKey(const Name& keyName)
 {
+  if(keyName.empty())
+    return Name();
+
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
 
@@ -586,6 +597,9 @@
 SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal(const Name& certificateName)
 {
   Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
+  if(keyName.empty())
+    throw Error("Incorrect key name for certificate " + certificateName.toUri());
+
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
 
@@ -693,6 +707,9 @@
 vector<Name>
 SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName, bool isDefault)
 {
+  if(keyName.empty())
+    return vector<Name>();
+
   sqlite3_stmt *stmt;
   if(isDefault)
     sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=1 and identity_name=? and key_identifier=?", -1, &stmt, 0);