tools: Adjust ndnsec-cert-gen behaivor

Refs: #1484

Change-Id: Id33a2881cc7a4c9acdd16999e80be7d79c63d650
diff --git a/src/security/sec-public-info-sqlite3.cpp b/src/security/sec-public-info-sqlite3.cpp
index b8b5af3..8d7ccb2 100644
--- a/src/security/sec-public-info-sqlite3.cpp
+++ b/src/security/sec-public-info-sqlite3.cpp
@@ -196,6 +196,9 @@
 void
 SecPublicInfoSqlite3::addIdentity(const Name& identityName)
 {
+  if (doesIdentityExist(identityName))
+    return;
+
   sqlite3_stmt* statement;
 
   sqlite3_prepare_v2(m_database, "INSERT OR REPLACE INTO Identity (identity_name) values (?)", -1, &statement, 0);
@@ -249,6 +252,9 @@
   if (keyName.empty())
     return;
 
+  if (doesPublicKeyExist(keyName))
+    return;
+
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
 
@@ -387,6 +393,9 @@
 
   addPublicKey(keyName, KEY_TYPE_RSA, certificate.getPublicKeyInfo()); //HACK!!! Assume the key type is RSA, we should check more.
 
+  if (doesCertificateExist(certificateName))
+    return;
+
   string keyId = keyName.get(-1).toEscapedString();
   Name identity = keyName.getPrefix(-1);
 
diff --git a/tools/ndnsec-cert-gen.hpp b/tools/ndnsec-cert-gen.hpp
index 796c3ed..24386b7 100644
--- a/tools/ndnsec-cert-gen.hpp
+++ b/tools/ndnsec-cert-gen.hpp
@@ -26,7 +26,7 @@
   std::string requestFile("-");
   std::string signId;
   std::string subjectInfo;
-  bool isSelfSigned = false;
+  bool hasSignId = false;
   bool isNack = false;
 
   po::options_description description("General Usage\n  ndnsec cert-gen [-h] [-S date] [-E date] [-N subject-name] [-I subject-info] [-s sign-id] request\nGeneral options");
@@ -37,7 +37,7 @@
     ("subject-name,N", po::value<std::string>(&subjectName), "subject name")
     ("subject-info,I", po::value<std::string>(&subjectInfo), "subject info, pairs of OID and string description: \"2.5.4.10 'University of California, Los Angeles'\"")
     ("nack", "Generate revocation certificate (NACK)")
-    ("sign-id,s", po::value<std::string>(&signId), "signing Identity, self-signed if not specified")
+    ("sign-id,s", po::value<std::string>(&signId), "signing Identity, system default identity if not specified")
     ("request,r", po::value<std::string>(&requestFile), "request file name, - for stdin")
     ;
 
@@ -63,9 +63,9 @@
       return 0;
     }
 
-  if (vm.count("sign-id") == 0)
+  if (vm.count("sign-id") != 0)
     {
-      isSelfSigned = true;
+      hasSignId = true;
     }
 
   if (vm.count("nack") != 0)
@@ -142,41 +142,39 @@
       return 1;
     }
 
+  KeyChain keyChain;
+
   Name keyName = selfSignedCertificate->getPublicKeyName();
   Name signIdName;
   Name certName;
 
-  if (isSelfSigned)
+  if (!hasSignId)
+    signIdName = keyChain.getDefaultIdentity();
+  else
+    signIdName = Name(signId);
+
+
+  if (signIdName.isPrefixOf(keyName))
     {
-      certName = keyName.getPrefix(keyName.size()-1);
-      certName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
+      // if signee's namespace is a sub-namespace of signer, for example, signer's namespace is
+      // /ndn/test, signee's namespace is /ndn/test/alice, the generated certificate name is
+      // /ndn/test/KEY/alice/ksk-1234/ID-CERT/%01%02
+      certName.append(signIdName)
+        .append("KEY")
+        .append(keyName.getSubName(signIdName.size()))
+        .append("ID-CERT")
+        .appendVersion();
     }
   else
     {
-      signIdName = Name(signId);
-
-      int count = 0;
-      Name::const_iterator i = keyName.begin();
-      Name::const_iterator j = signIdName.begin();
-      for (; i != keyName.end() && j != signIdName.end(); i++, j++)
-        {
-          if (*i != *j)
-            break;
-
-          count++;
-        }
-
-      if (j != signIdName.end() || i == keyName.end())
-        {
-          std::cerr << "wrong signing identity!" << std::endl;
-          return 1;
-        }
-
-      certName = keyName.getSubName(0, count);
-      certName.append("KEY")
-        .append(keyName.getSubName(count, keyName.size() - count))
+      // if signee's namespace is not a sub-namespace of signer, for example, signer's namespace is
+      // /ndn/test, signee's namespace is /ndn/ucla/bob, the generated certificate name is
+      // /ndn/ucla/bob/KEY/ksk-1234/ID-CERT/%01%02
+      certName.append(keyName.getPrefix(-1))
+        .append("KEY")
+        .append(keyName.get(-1))
         .append("ID-CERT")
-        .appendVersion ();
+        .appendVersion();
     }
 
   Block wire;
@@ -200,17 +198,10 @@
         certificate.addSubjectDescription(otherSubDescrypt[i]);
       certificate.encode();
 
-      KeyChain keyChain;
+      keyChain.createIdentity(signIdName);
+      Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(signIdName);
+      keyChain.sign(certificate, signingCertificateName);
 
-      if (isSelfSigned)
-        keyChain.selfSign(certificate);
-      else
-        {
-          Name signingCertificateName =
-            keyChain.getDefaultCertificateNameForIdentity(Name(signId));
-
-          keyChain.sign(certificate, signingCertificateName);
-        }
       wire = certificate.wireEncode();
     }
   else
@@ -219,12 +210,10 @@
       // revocationCert.setContent(void*, 0); // empty content
       revocationCert.setName(certName);
 
-      KeyChain keyChain;
-
-      Name signingCertificateName =
-        keyChain.getDefaultCertificateNameForIdentity(signId);
-
+      keyChain.createIdentity(signIdName);
+      Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(signIdName);
       keyChain.sign(revocationCert, signingCertificateName);
+
       wire = revocationCert.wireEncode();
     }
 
diff --git a/tools/ndnsec.cpp b/tools/ndnsec.cpp
index 24026e0..135be48 100644
--- a/tools/ndnsec.cpp
+++ b/tools/ndnsec.cpp
@@ -42,9 +42,9 @@
   set-acl      Configure ACL of a private key.\n\
   unlock-tpm   Unlock Tpm.\n\
   op-tool      Operator tool.\n\
-"); 
+");
 
-int 
+int
 main(int argc, char** argv)
 {
   if (argc < 2)