Adding optional initial vector to EncryptedContent

Refs: #3013

Change-Id: I1c6fea3552796d13525d33e3a9d385156e2d463e
diff --git a/tests/unit-tests/encrypted-content.t.cpp b/tests/unit-tests/encrypted-content.t.cpp
index e53b3f1..878d0e9 100644
--- a/tests/unit-tests/encrypted-content.t.cpp
+++ b/tests/unit-tests/encrypted-content.t.cpp
@@ -29,6 +29,24 @@
 BOOST_AUTO_TEST_SUITE(TestEncryptedContent)
 
 const uint8_t encrypted[] = {
+0x82, 0x30, // EncryptedContent
+  0x1c, 0x16, // KeyLocator
+    0x07, 0x14, // Name
+      0x08, 0x04,
+        0x74, 0x65, 0x73, 0x74, // 'test'
+      0x08, 0x03,
+        0x6b, 0x65, 0x79, // 'key'
+      0x08, 0x07,
+        0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, // 'locator'
+  0x83, 0x01, // EncryptedAlgorithm
+    0x00,
+  0x85, 0x0a, // InitialVector
+    0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
+  0x84, 0x07, // EncryptedPayload
+    0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
+};
+
+const uint8_t encrypted_noiv[] = {
 0x82, 0x24, // EncryptedContent
   0x1c, 0x16, // KeyLocator
     0x07, 0x14, // Name
@@ -48,24 +66,36 @@
   0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
 };
 
+const uint8_t iv[] = {
+  0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73
+};
+
 BOOST_AUTO_TEST_CASE(Constructor)
 {
   EncryptedContent content;
   BOOST_CHECK_EQUAL(content.getAlgorithmType(), -1);
   BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+  BOOST_CHECK_EQUAL(content.getInitialVector() == nullptr, true);
   BOOST_CHECK_EQUAL(content.hasKeyLocator(), false);
   BOOST_CHECK_THROW(content.getKeyLocator(), EncryptedContent::Error);
 
   ConstBufferPtr payload = make_shared<Buffer>(message, sizeof(message));
+  ConstBufferPtr initialVector = make_shared<Buffer>(iv, sizeof(iv));
+
   KeyLocator keyLocator("test/key/locator");
-  EncryptedContent sha256RsaContent(tlv::AlgorithmSha256WithRsa, keyLocator, payload);
+  EncryptedContent sha256RsaContent(tlv::AlgorithmSha256WithRsa, keyLocator, payload, initialVector);
   ConstBufferPtr contentPayload = sha256RsaContent.getPayload();
+  ConstBufferPtr contentInitialVector = sha256RsaContent.getInitialVector();
 
   BOOST_CHECK_EQUAL(sha256RsaContent.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
   BOOST_CHECK_EQUAL_COLLECTIONS(contentPayload->begin(),
                                 contentPayload->end(),
                                 payload->begin(),
                                 payload->end());
+  BOOST_CHECK_EQUAL_COLLECTIONS(contentInitialVector->begin(),
+                                contentInitialVector->end(),
+                                initialVector->begin(),
+                                initialVector->end());
   BOOST_CHECK_EQUAL(sha256RsaContent.hasKeyLocator(), true);
   BOOST_CHECK_NO_THROW(sha256RsaContent.getKeyLocator());
   BOOST_CHECK_EQUAL(sha256RsaContent.getKeyLocator().getName(), Name("test/key/locator"));
@@ -80,6 +110,7 @@
 
   sha256RsaContent = EncryptedContent(encryptedBlock);
   contentPayload = sha256RsaContent.getPayload();
+  contentInitialVector = sha256RsaContent.getInitialVector();
 
   BOOST_CHECK_EQUAL(sha256RsaContent.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
   BOOST_CHECK_EQUAL(sha256RsaContent.hasKeyLocator(), true);
@@ -87,14 +118,52 @@
                                 contentPayload->end(),
                                 payload->begin(),
                                 payload->end());
+  BOOST_CHECK_EQUAL_COLLECTIONS(contentInitialVector->begin(),
+                                contentInitialVector->end(),
+                                initialVector->begin(),
+                                initialVector->end());
   BOOST_CHECK_NO_THROW(sha256RsaContent.getKeyLocator());
   BOOST_CHECK_EQUAL(sha256RsaContent.getKeyLocator().getName(), Name("test/key/locator"));
+
+  sha256RsaContent = EncryptedContent(tlv::AlgorithmSha256WithRsa, keyLocator, payload);
+
+  BOOST_CHECK_EQUAL(sha256RsaContent.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
+  BOOST_CHECK_EQUAL_COLLECTIONS(contentPayload->begin(),
+                                contentPayload->end(),
+                                payload->begin(),
+                                payload->end());
+  BOOST_CHECK_EQUAL(sha256RsaContent.getInitialVector() == nullptr, true);
+  BOOST_CHECK_EQUAL(sha256RsaContent.hasKeyLocator(), true);
+  BOOST_CHECK_NO_THROW(sha256RsaContent.getKeyLocator());
+  BOOST_CHECK_EQUAL(sha256RsaContent.getKeyLocator().getName(), Name("test/key/locator"));
+
+  encryptedBlock = Block(encrypted_noiv, sizeof(encrypted_noiv));
+  const Block& encodedNoIV = sha256RsaContent.wireEncode();
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(encryptedBlock.wire(),
+                                encryptedBlock.wire() + encryptedBlock.size(),
+                                encodedNoIV.wire(),
+                                encodedNoIV.wire() + encodedNoIV.size());
+
+  sha256RsaContent = EncryptedContent(encryptedBlock);
+  contentPayload = sha256RsaContent.getPayload();
+
+  BOOST_CHECK_EQUAL(sha256RsaContent.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
+  BOOST_CHECK_EQUAL(sha256RsaContent.hasKeyLocator(), true);
+  BOOST_CHECK_EQUAL_COLLECTIONS(contentPayload->begin(),
+                                contentPayload->end(),
+                                payload->begin(),
+                                payload->end());
+  BOOST_CHECK_EQUAL(sha256RsaContent.getInitialVector() == nullptr, true);
+  BOOST_CHECK_NO_THROW(sha256RsaContent.getKeyLocator());
+  BOOST_CHECK_EQUAL(sha256RsaContent.getKeyLocator().getName(), Name("test/key/locator"));
+
 }
 
 BOOST_AUTO_TEST_CASE(ConstructorError)
 {
   const uint8_t error1[] = {
-    0x1f, 0x24, // Wrong EncryptedContent (0x82, 0x24)
+    0x1f, 0x30, // Wrong EncryptedContent (0x82, 0x24)
       0x1c, 0x16, // KeyLocator
         0x07, 0x14, // Name
           0x08, 0x04,
@@ -105,6 +174,8 @@
             0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
       0x83, 0x01, // EncryptedAlgorithm
         0x00,
+      0x85, 0x0a, // InitialVector
+        0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
       0x84, 0x07, // EncryptedPayload
         0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
   };
@@ -112,7 +183,7 @@
   BOOST_CHECK_THROW(EncryptedContent info(errorBlock1), EncryptedContent::Error);
 
   const uint8_t error2[] = {
-    0x82, 0x24, // EncryptedContent
+    0x82, 0x30, // EncryptedContent
       0x1d, 0x16, // Wrong KeyLocator (0x1c, 0x16)
         0x07, 0x14, // Name
           0x08, 0x04,
@@ -123,6 +194,8 @@
             0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
       0x83, 0x01, // EncryptedAlgorithm
         0x00,
+      0x85, 0x0a, // InitialVector
+        0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
       0x84, 0x07, // EncryptedPayload
         0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
   };
@@ -130,7 +203,7 @@
   BOOST_CHECK_THROW(EncryptedContent info(errorBlock2), EncryptedContent::Error);
 
   const uint8_t error3[] = {
-    0x82, 0x24, // EncryptedContent
+    0x82, 0x30, // EncryptedContent
       0x1c, 0x16, // KeyLocator
         0x07, 0x14, // Name
           0x08, 0x04,
@@ -141,6 +214,8 @@
             0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
       0x1d, 0x01, // Wrong EncryptedAlgorithm (0x83, 0x01)
         0x00,
+      0x85, 0x0a, // InitialVector
+        0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
       0x84, 0x07, // EncryptedPayload
         0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
   };
@@ -148,7 +223,7 @@
   BOOST_CHECK_THROW(EncryptedContent info(errorBlock3), EncryptedContent::Error);
 
   const uint8_t error4[] = {
-    0x82, 0x24, // EncryptedContent
+    0x82, 0x30, // EncryptedContent
       0x1c, 0x16, // KeyLocator
         0x07, 0x14, // Name
           0x08, 0x04,
@@ -159,17 +234,39 @@
             0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, // 'locator'
       0x83, 0x01, // EncryptedAlgorithm
         0x00,
-      0x21, 0x07, // EncryptedPayload (0x84, 0x07)
+      0x1f, 0x0a, // InitialVector (0x84, 0x0a)
+        0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
+      0x84, 0x07, // EncryptedPayload
         0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
   };
   Block errorBlock4(error4, sizeof(error4));
   BOOST_CHECK_THROW(EncryptedContent info(errorBlock4), EncryptedContent::Error);
 
   const uint8_t error5[] = {
-    0x82, 0x00 // Empty EncryptedContent
+    0x82, 0x30, // EncryptedContent
+      0x1c, 0x16, // KeyLocator
+        0x07, 0x14, // Name
+          0x08, 0x04,
+            0x74, 0x65, 0x73, 0x74, // 'test'
+          0x08, 0x03,
+            0x6b, 0x65, 0x79, // 'key'
+          0x08, 0x07,
+            0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, // 'locator'
+      0x83, 0x01, // EncryptedAlgorithm
+        0x00,
+      0x85, 0x0a, // InitialVector
+        0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
+      0x21, 0x07, // EncryptedPayload (0x85, 0x07)
+        0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
   };
   Block errorBlock5(error5, sizeof(error5));
   BOOST_CHECK_THROW(EncryptedContent info(errorBlock5), EncryptedContent::Error);
+
+  const uint8_t error6[] = {
+    0x82, 0x00 // Empty EncryptedContent
+  };
+  Block errorBlock6(error6, sizeof(error6));
+  BOOST_CHECK_THROW(EncryptedContent info(errorBlock6), EncryptedContent::Error);
 }
 
 BOOST_AUTO_TEST_CASE(SetterGetter)
@@ -177,12 +274,14 @@
   EncryptedContent content;
   BOOST_CHECK_EQUAL(content.getAlgorithmType(), -1);
   BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+  BOOST_CHECK_EQUAL(content.getInitialVector() == nullptr, true);
   BOOST_CHECK_EQUAL(content.hasKeyLocator(), false);
   BOOST_CHECK_THROW(content.getKeyLocator(), EncryptedContent::Error);
 
   content.setAlgorithmType(tlv::AlgorithmSha256WithRsa);
   BOOST_CHECK_EQUAL(content.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
   BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+  BOOST_CHECK_EQUAL(content.getInitialVector() == nullptr, true);
   BOOST_CHECK_EQUAL(content.hasKeyLocator(), false);
 
   KeyLocator keyLocator("/test/key/locator");
@@ -191,6 +290,7 @@
   BOOST_CHECK_NO_THROW(content.getKeyLocator());
   BOOST_CHECK_EQUAL(content.getKeyLocator().getName(), Name("/test/key/locator"));
   BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+  BOOST_CHECK_EQUAL(content.getInitialVector() == nullptr, true);
 
   ConstBufferPtr payload = make_shared<Buffer>(message, sizeof(message));
   content.setPayload(payload);
@@ -201,6 +301,15 @@
                                 payload->begin(),
                                 payload->end());
 
+  ConstBufferPtr initialVector = make_shared<Buffer>(iv, sizeof(iv));
+  content.setInitialVector(initialVector);
+
+  ConstBufferPtr contentInitialVector = content.getInitialVector();
+  BOOST_CHECK_EQUAL_COLLECTIONS(contentInitialVector->begin(),
+                                contentInitialVector->end(),
+                                initialVector->begin(),
+                                initialVector->end());
+
   const Block& encoded = content.wireEncode();
   Block contentBlock(encrypted, sizeof(encrypted));