Botan  1.11.15
src/lib/asn1/oid_lookup/oids.cpp
Go to the documentation of this file.
00001 /*
00002 * OID Registry
00003 * (C) 1999-2008,2013 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/oids.h>
00009 #include <botan/parsing.h>
00010 #include <mutex>
00011 #include <sstream>
00012 
00013 namespace Botan {
00014 
00015 namespace OIDS {
00016 
00017 namespace {
00018 
00019 class OID_Map
00020    {
00021    public:
00022       void add_oid(const OID& oid, const std::string& str)
00023          {
00024          add_str2oid(oid, str);
00025          add_oid2str(oid, str);
00026          }
00027 
00028       void add_str2oid(const OID& oid, const std::string& str)
00029          {
00030          std::lock_guard<std::mutex> lock(m_mutex);
00031          auto i = m_str2oid.find(str);
00032          if(i == m_str2oid.end())
00033             m_str2oid.insert(std::make_pair(str, oid));
00034          }
00035 
00036       void add_oid2str(const OID& oid, const std::string& str)
00037          {
00038          std::lock_guard<std::mutex> lock(m_mutex);
00039          auto i = m_oid2str.find(oid);
00040          if(i == m_oid2str.end())
00041             m_oid2str.insert(std::make_pair(oid, str));
00042          }
00043 
00044       std::string lookup(const OID& oid)
00045          {
00046          std::lock_guard<std::mutex> lock(m_mutex);
00047 
00048          auto i = m_oid2str.find(oid);
00049          if(i != m_oid2str.end())
00050             return i->second;
00051 
00052          return "";
00053          }
00054 
00055       OID lookup(const std::string& str)
00056          {
00057          std::lock_guard<std::mutex> lock(m_mutex);
00058 
00059          auto i = m_str2oid.find(str);
00060          if(i != m_str2oid.end())
00061             return i->second;
00062 
00063          // Try to parse as plain OID
00064          try
00065             {
00066             return OID(str);
00067             }
00068          catch(...) {}
00069 
00070          throw Lookup_Error("No object identifier found for " + str);
00071          }
00072 
00073       bool have_oid(const std::string& str)
00074          {
00075          std::lock_guard<std::mutex> lock(m_mutex);
00076          return m_str2oid.find(str) != m_str2oid.end();
00077          }
00078 
00079       static OID_Map& global_registry()
00080          {
00081          static OID_Map g_map;
00082          return g_map;
00083          }
00084 
00085       void read_cfg(std::istream& cfg, const std::string& source);
00086 
00087    private:
00088 
00089       OID_Map()
00090          {
00091          std::istringstream cfg(default_oid_list());
00092          read_cfg(cfg, "builtin");
00093          }
00094 
00095       std::mutex m_mutex;
00096       std::map<std::string, OID> m_str2oid;
00097       std::map<OID, std::string> m_oid2str;
00098    };
00099 
00100 void OID_Map::read_cfg(std::istream& cfg, const std::string& source)
00101    {
00102    std::lock_guard<std::mutex> lock(m_mutex);
00103 
00104    size_t line = 0;
00105 
00106    while(cfg.good())
00107       {
00108       std::string s;
00109       std::getline(cfg, s);
00110       ++line;
00111 
00112       if(s == "" || s[0] == '#')
00113          continue;
00114 
00115       s = clean_ws(s.substr(0, s.find('#')));
00116 
00117       if(s == "")
00118          continue;
00119 
00120       auto eq = s.find("=");
00121 
00122       if(eq == std::string::npos || eq == 0 || eq == s.size() - 1)
00123          throw std::runtime_error("Bad config line '" + s + "' in " + source + " line " + std::to_string(line));
00124 
00125       const std::string oid = clean_ws(s.substr(0, eq));
00126       const std::string name = clean_ws(s.substr(eq + 1, std::string::npos));
00127 
00128       m_str2oid.insert(std::make_pair(name, oid));
00129       m_oid2str.insert(std::make_pair(oid, name));
00130       }
00131    }
00132 
00133 }
00134 
00135 void add_oid(const OID& oid, const std::string& name)
00136    {
00137    OID_Map::global_registry().add_oid(oid, name);
00138    }
00139 
00140 void add_oidstr(const char* oidstr, const char* name)
00141    {
00142    add_oid(OID(oidstr), name);
00143    }
00144 
00145 void add_oid2str(const OID& oid, const std::string& name)
00146    {
00147    OID_Map::global_registry().add_oid2str(oid, name);
00148    }
00149 
00150 void add_str2oid(const OID& oid, const std::string& name)
00151    {
00152    OID_Map::global_registry().add_str2oid(oid, name);
00153    }
00154 
00155 std::string lookup(const OID& oid)
00156    {
00157    return OID_Map::global_registry().lookup(oid);
00158    }
00159 
00160 OID lookup(const std::string& name)
00161    {
00162    return OID_Map::global_registry().lookup(name);
00163    }
00164 
00165 bool have_oid(const std::string& name)
00166    {
00167    return OID_Map::global_registry().have_oid(name);
00168    }
00169 
00170 bool name_of(const OID& oid, const std::string& name)
00171    {
00172    return (oid == lookup(name));
00173    }
00174 
00175 }
00176 
00177 }