security: Add ECDSA signature signing and validation

Change-Id: I2f193e9d643498a68579ae59a7f524ff446dcb9e
Refs: #1660
diff --git a/src/security/validator.cpp b/src/security/validator.cpp
index 29a4801..df7b0e6 100644
--- a/src/security/validator.cpp
+++ b/src/security/validator.cpp
@@ -29,10 +29,11 @@
 
 #include "cryptopp.hpp"
 
-using namespace std;
-
 namespace ndn {
 
+static OID SECP256R1("1.2.840.10045.3.1.7");
+static OID SECP384R1("1.3.132.0.34");
+
 Validator::Validator()
   : m_hasFace(false)
   , m_face(*static_cast<Face*>(0))
@@ -51,7 +52,7 @@
                     const OnInterestValidationFailed& onValidationFailed,
                     int nSteps)
 {
-  vector<shared_ptr<ValidationRequest> > nextSteps;
+  std::vector<shared_ptr<ValidationRequest> > nextSteps;
   checkPolicy(interest, nSteps, onValidated, onValidationFailed, nextSteps);
 
   if (!nextSteps.empty())
@@ -63,7 +64,7 @@
           return;
         }
 
-      vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
+      std::vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
       OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
       for (; it != nextSteps.end(); it++)
         m_face.expressInterest((*it)->m_interest,
@@ -87,7 +88,7 @@
                     const OnDataValidationFailed& onValidationFailed,
                     int nSteps)
 {
-  vector<shared_ptr<ValidationRequest> > nextSteps;
+  std::vector<shared_ptr<ValidationRequest> > nextSteps;
   checkPolicy(data, nSteps, onValidated, onValidationFailed, nextSteps);
 
   if (!nextSteps.empty())
@@ -98,7 +99,7 @@
                              "Require more information to validate the data!");
         }
 
-      vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
+      std::vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
       OnFailure onFailure = bind(onValidationFailed, data.shared_from_this(), _1);
       for (; it != nextSteps.end(); it++)
         m_face.expressInterest((*it)->m_interest,
@@ -147,13 +148,25 @@
     {
       switch (data.getSignature().getType())
         {
-        case Signature::Sha256WithRsa:
+        case Tlv::SignatureSha256WithRsa:
           {
             SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
-            return verifySignature(data, sigSha256Rsa, key);
+            return verifySignature(data.wireEncode().value(),
+                                   data.wireEncode().value_size() -
+                                   data.getSignature().getValue().size(),
+                                   sigSha256Rsa, key);
           }
+        case Tlv::SignatureSha256WithEcdsa:
+          {
+            SignatureSha256WithEcdsa sigSha256Ecdsa(data.getSignature());
+            return verifySignature(data.wireEncode().value(),
+                                   data.wireEncode().value_size() -
+                                   data.getSignature().getValue().size(),
+                                   sigSha256Ecdsa, key);
+           }
         default:
           {
+            // Unsupported sig type
             return false;
           }
         }
@@ -182,7 +195,7 @@
 
       switch (sig.getType())
         {
-        case Signature::Sha256WithRsa:
+        case Tlv::SignatureSha256WithRsa:
           {
             SignatureSha256WithRsa sigSha256Rsa(sig);
 
@@ -190,8 +203,17 @@
                                    nameBlock.value_size() - interestName[-1].size(),
                                    sigSha256Rsa, key);
           }
+        case Tlv::SignatureSha256WithEcdsa:
+          {
+            SignatureSha256WithEcdsa sigSha256Ecdsa(sig);
+
+            return verifySignature(nameBlock.value(),
+                                   nameBlock.value_size() - interestName[-1].size(),
+                                   sigSha256Ecdsa, key);
+          }
         default:
           {
+            // Unsupported sig type
             return false;
           }
         }
@@ -208,50 +230,94 @@
 }
 
 bool
-Validator::verifySignature(const Buffer& data, const Signature& sig, const PublicKey& key)
-{
-  try
-    {
-      switch (sig.getType())
-        {
-        case Signature::Sha256WithRsa:
-          {
-            SignatureSha256WithRsa sigSha256Rsa(sig);
-            return verifySignature(data, sigSha256Rsa, key);
-          }
-        default:
-          {
-            return false;
-          }
-        }
-    }
-  catch (Signature::Error& e)
-    {
-      return false;
-    }
-  return false;
-}
-
-bool
 Validator::verifySignature(const uint8_t* buf,
                            const size_t size,
-                           const SignatureSha256WithRsa& sig,
+                           const SignatureWithPublicKey& sig,
                            const PublicKey& key)
 {
   try
     {
       using namespace CryptoPP;
 
-      RSA::PublicKey publicKey;
-      ByteQueue queue;
+      switch (sig.getType())
+        {
+        case Tlv::SignatureSha256WithRsa:
+          {
+            if (key.getKeyType() != KEY_TYPE_RSA)
+              return false;
 
-      queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
-      publicKey.Load(queue);
+            RSA::PublicKey publicKey;
+            ByteQueue queue;
 
-      RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
-      return verifier.VerifyMessage(buf, size,
-                                    sig.getValue().value(),
-                                    sig.getValue().value_size());
+            queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
+            publicKey.Load(queue);
+
+            RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
+            return verifier.VerifyMessage(buf, size,
+                                          sig.getValue().value(), sig.getValue().value_size());
+          }
+        case Tlv::SignatureSha256WithEcdsa:
+          {
+            if (key.getKeyType() != KEY_TYPE_ECDSA)
+              return false;
+
+            ECDSA<ECP, SHA256>::PublicKey publicKey;
+            ByteQueue queue;
+
+            queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
+            publicKey.Load(queue);
+
+            ECDSA<ECP, SHA256>::Verifier verifier(publicKey);
+
+            uint32_t length = 0;
+            StringSource src(key.get().buf(), key.get().size(), true);
+            BERSequenceDecoder subjectPublicKeyInfo(src);
+            {
+              BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
+              {
+                OID algorithm;
+                algorithm.decode(algorithmInfo);
+
+                OID curveId;
+                curveId.decode(algorithmInfo);
+
+                if (curveId == SECP256R1)
+                  length = 256;
+                else if (curveId == SECP384R1)
+                  length = 384;
+                else
+                  return false;
+              }
+            }
+
+            switch (length)
+              {
+              case 256:
+                {
+                  uint8_t buffer[64];
+                  size_t usedSize = DSAConvertSignatureFormat(buffer, 64, DSA_P1363,
+                                                              sig.getValue().value(),
+                                                              sig.getValue().value_size(),
+                                                              DSA_DER);
+                  return verifier.VerifyMessage(buf, size, buffer, usedSize);
+                }
+              case 384:
+                {
+                  uint8_t buffer[96];
+                  size_t usedSize = DSAConvertSignatureFormat(buffer, 96, DSA_P1363,
+                                                              sig.getValue().value(),
+                                                              sig.getValue().value_size(),
+                                                              DSA_DER);
+                  return verifier.VerifyMessage(buf, size, buffer, usedSize);
+                }
+              default:
+                return false;
+              }
+          }
+        default:
+          // Unsupported sig type
+          return false;
+        }
     }
   catch (CryptoPP::Exception& e)
     {