aboutsummaryrefslogtreecommitdiffstats
path: root/src/asn1/asn1_oid.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-09-28 22:14:54 +0000
committerlloyd <[email protected]>2008-09-28 22:14:54 +0000
commit31204986023619c385d378e79a6511bb81ef7b78 (patch)
treece272a6585dc070f750f6875b0450d53145b935d /src/asn1/asn1_oid.cpp
parent42c0fe76ab6d9625d0e51c68b8dd187322c991bd (diff)
Move almost all of the ASN.1, BER, and DER codec related code into new
module asn1 Move hex and base64 codecs into new codecs directory. Also move zlib and bzip2 to codecs from compress.
Diffstat (limited to 'src/asn1/asn1_oid.cpp')
-rw-r--r--src/asn1/asn1_oid.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/asn1/asn1_oid.cpp b/src/asn1/asn1_oid.cpp
new file mode 100644
index 000000000..80968ed8f
--- /dev/null
+++ b/src/asn1/asn1_oid.cpp
@@ -0,0 +1,174 @@
+/*************************************************
+* ASN.1 OID Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/asn1_oid.h>
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
+#include <botan/bit_ops.h>
+#include <botan/parsing.h>
+
+namespace Botan {
+
+/*************************************************
+* ASN.1 OID Constructor *
+*************************************************/
+OID::OID(const std::string& oid_str)
+ {
+ if(oid_str != "")
+ {
+ id = parse_asn1_oid(oid_str);
+ if(id.size() < 2 || id[0] > 2)
+ throw Invalid_OID(oid_str);
+ if((id[0] == 0 || id[0] == 1) && id[1] > 39)
+ throw Invalid_OID(oid_str);
+ }
+ }
+
+/*************************************************
+* Clear the current OID *
+*************************************************/
+void OID::clear()
+ {
+ id.clear();
+ }
+
+/*************************************************
+* Return this OID as a string *
+*************************************************/
+std::string OID::as_string() const
+ {
+ std::string oid_str;
+ for(u32bit j = 0; j != id.size(); ++j)
+ {
+ oid_str += to_string(id[j]);
+ if(j != id.size() - 1)
+ oid_str += '.';
+ }
+ return oid_str;
+ }
+
+/*************************************************
+* OID equality comparison *
+*************************************************/
+bool OID::operator==(const OID& oid) const
+ {
+ if(id.size() != oid.id.size())
+ return false;
+ for(u32bit j = 0; j != id.size(); ++j)
+ if(id[j] != oid.id[j])
+ return false;
+ return true;
+ }
+
+/*************************************************
+* Append another component to the OID *
+*************************************************/
+OID& OID::operator+=(u32bit component)
+ {
+ id.push_back(component);
+ return (*this);
+ }
+
+/*************************************************
+* Append another component to the OID *
+*************************************************/
+OID operator+(const OID& oid, u32bit component)
+ {
+ OID new_oid(oid);
+ new_oid += component;
+ return new_oid;
+ }
+
+/*************************************************
+* OID inequality comparison *
+*************************************************/
+bool operator!=(const OID& a, const OID& b)
+ {
+ return !(a == b);
+ }
+
+/*************************************************
+* Compare two OIDs *
+*************************************************/
+bool operator<(const OID& a, const OID& b)
+ {
+ std::vector<u32bit> oid1 = a.get_id();
+ std::vector<u32bit> oid2 = b.get_id();
+
+ if(oid1.size() < oid2.size())
+ return true;
+ if(oid1.size() > oid2.size())
+ return false;
+ for(u32bit j = 0; j != oid1.size(); ++j)
+ {
+ if(oid1[j] < oid2[j])
+ return true;
+ if(oid1[j] > oid2[j])
+ return false;
+ }
+ return false;
+ }
+
+/*************************************************
+* DER encode an OBJECT IDENTIFIER *
+*************************************************/
+void OID::encode_into(DER_Encoder& der) const
+ {
+ if(id.size() < 2)
+ throw Invalid_Argument("OID::encode_into: OID is invalid");
+
+ MemoryVector<byte> encoding;
+ encoding.append(40 * id[0] + id[1]);
+
+ for(u32bit j = 2; j != id.size(); ++j)
+ {
+ if(id[j] == 0)
+ encoding.append(0);
+ else
+ {
+ u32bit blocks = high_bit(id[j]) + 6;
+ blocks = (blocks - (blocks % 7)) / 7;
+
+ for(u32bit k = 0; k != blocks - 1; ++k)
+ encoding.append(0x80 | ((id[j] >> 7*(blocks-k-1)) & 0x7F));
+ encoding.append(id[j] & 0x7F);
+ }
+ }
+ der.add_object(OBJECT_ID, UNIVERSAL, encoding);
+ }
+
+/*************************************************
+* Decode a BER encoded OBJECT IDENTIFIER *
+*************************************************/
+void OID::decode_from(BER_Decoder& decoder)
+ {
+ BER_Object obj = decoder.get_next_object();
+ if(obj.type_tag != OBJECT_ID || obj.class_tag != UNIVERSAL)
+ throw BER_Bad_Tag("Error decoding OID, unknown tag",
+ obj.type_tag, obj.class_tag);
+ if(obj.value.size() < 2)
+ throw BER_Decoding_Error("OID encoding is too short");
+
+
+ clear();
+ id.push_back(obj.value[0] / 40);
+ id.push_back(obj.value[0] % 40);
+
+ u32bit j = 0;
+ while(j != obj.value.size() - 1)
+ {
+ u32bit component = 0;
+ while(j != obj.value.size() - 1)
+ {
+ ++j;
+ component = (component << 7) + (obj.value[j] & 0x7F);
+ if(!(obj.value[j] & 0x80))
+ break;
+ }
+ id.push_back(component);
+ }
+ }
+
+}