Botan
1.11.15
|
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 }