security: CryptoPP functions are used directly to encode/decode DER/BER
This change eliminates the need for custom der decoder/encoder.
Change-Id: I5be2e55cec2b63157927a4ad87fffe8e8651ed3c
diff --git a/src/encoding/oid.cpp b/src/encoding/oid.cpp
index 633d1cf..2db72f7 100644
--- a/src/encoding/oid.cpp
+++ b/src/encoding/oid.cpp
@@ -9,8 +9,10 @@
#include <sstream>
#include <ndn-cpp/encoding/oid.hpp>
+#include <cryptopp/asn.h>
using namespace std;
+using namespace CryptoPP;
namespace ndn {
@@ -48,7 +50,8 @@
return convert.str();
}
-bool OID::equal(const OID& oid) const
+bool
+OID::equal(const OID& oid) const
{
vector<int>::const_iterator i = oid_.begin();
vector<int>::const_iterator j = oid.oid_.begin();
@@ -64,4 +67,75 @@
return false;
}
+inline void
+EncodeValue(BufferedTransformation &bt, word32 v)
+{
+ for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
+ bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
+ bt.Put((byte)(v & 0x7f));
+}
+
+inline size_t
+DecodeValue(BufferedTransformation &bt, word32 &v)
+{
+ byte b;
+ size_t i=0;
+ v = 0;
+ while (true)
+ {
+ if (!bt.Get(b))
+ BERDecodeError();
+ i++;
+ if (v >> (8*sizeof(v)-7)) // v about to overflow
+ BERDecodeError();
+ v <<= 7;
+ v += b & 0x7f;
+ if (!(b & 0x80))
+ return i;
+ }
+}
+
+void
+OID::encode(CryptoPP::BufferedTransformation &out) const
+{
+ assert(oid_.size() >= 2);
+ ByteQueue temp;
+ temp.Put(byte(oid_[0] * 40 + oid_[1]));
+ for (size_t i=2; i<oid_.size(); i++)
+ EncodeValue(temp, oid_[i]);
+ out.Put(OBJECT_IDENTIFIER);
+ DERLengthEncode(out, temp.CurrentSize());
+ temp.TransferTo(out);
+}
+
+void
+OID::decode(CryptoPP::BufferedTransformation &in)
+{
+ byte b;
+ if (!in.Get(b) || b != OBJECT_IDENTIFIER)
+ BERDecodeError();
+
+ size_t length;
+ if (!BERLengthDecode(in, length) || length < 1)
+ BERDecodeError();
+
+ if (!in.Get(b))
+ BERDecodeError();
+
+ length--;
+ oid_.resize(2);
+ oid_[0] = b / 40;
+ oid_[1] = b % 40;
+
+ while (length > 0)
+ {
+ word32 v;
+ size_t valueLen = DecodeValue(in, v);
+ if (valueLen > length)
+ BERDecodeError();
+ oid_.push_back(v);
+ length -= valueLen;
+ }
+}
+
}