summaryrefslogtreecommitdiffabout
path: root/lib/util.cc
Side-by-side diff
Diffstat (limited to 'lib/util.cc') (more/less context) (show whitespace changes)
-rw-r--r--lib/util.cc71
1 files changed, 69 insertions, 2 deletions
diff --git a/lib/util.cc b/lib/util.cc
index a9b9bed..54d6535 100644
--- a/lib/util.cc
+++ b/lib/util.cc
@@ -1,25 +1,31 @@
#include <errno.h>
#include <cassert>
#include <cctype>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <openssl/bio.h>
#include <openssl/evp.h>
+#include <openssl/hmac.h>
#include <curl/curl.h>
#include "opkele/util.h"
#include "opkele/exception.h"
+#include <config.h>
+#ifdef HAVE_DEMANGLE
+# include <cxxabi.h>
+#endif
+
namespace opkele {
using namespace std;
namespace util {
/*
* base64
*/
string encode_base64(const void *data,size_t length) {
BIO *b64 = 0, *bmem = 0;
try {
b64 = BIO_new(BIO_f_base64());
@@ -196,26 +202,25 @@ namespace opkele {
back_inserter(rv), ::tolower );
bool s;
string::size_type ul = uri.find_last_not_of(whitespace)+1;
if(ul <= (colon+3))
throw bad_input(OPKELE_CP_ "Unexpected end of URI being normalized encountered");
if(uri[colon+1]!='/' || uri[colon+2]!='/')
throw bad_input(OPKELE_CP_ "Unexpected input in URI being normalized after scheme component");
if(rv=="http:")
s = false;
else if(rv=="https:")
s = true;
else{
- /* TODO: support more schemes.
- * e.g. xri. How do we normalize
+ /* TODO: support more schemes. e.g. xri. How do we normalize
* xri?
*/
rv.append(uri,colon+1,ul-colon-1);
return rv;
}
rv += "//";
string::size_type interesting = uri.find_first_of(":/#?",colon+3);
if(interesting==string::npos) {
transform(
uri.begin()+colon+3,uri.begin()+ul,
back_inserter(rv), ::tolower );
rv += '/'; return rv;
@@ -302,15 +307,77 @@ namespace opkele {
pseg.clear();
}else{
pseg += c;
}
}
if(!pseg.empty()) {
if(!qf) rv += '/';
rv += pseg;
}
return rv;
}
+ string& strip_uri_fragment_part(string& u) {
+ string::size_type q = u.find('?'), f = u.find('#');
+ if(q==string::npos) {
+ if(f!=string::npos)
+ u.erase(f);
+ }else{
+ if(f!=string::npos) {
+ if(f<q)
+ u.erase(f,q-f);
+ else
+ u.erase(f);
+ }
+ }
+ return u;
+ }
+
+ string abi_demangle(const char *mn) {
+#ifndef HAVE_DEMANGLE
+ return mn;
+#else /* !HAVE_DEMANGLE */
+ int dstat;
+ char *demangled = abi::__cxa_demangle(mn,0,0,&dstat);
+ if(dstat)
+ return mn;
+ string rv = demangled;
+ free(demangled);
+ return rv;
+#endif /* !HAVE_DEMANGLE */
+ }
+
+ string base64_signature(const assoc_t& assoc,const basic_openid_message& om) {
+ const string& slist = om.get_field("signed");
+ string kv;
+ string::size_type p=0;
+ while(true) {
+ string::size_type co = slist.find(',',p);
+ string f = (co==string::npos)
+ ?slist.substr(p):slist.substr(p,co-p);
+ kv += f;
+ kv += ':';
+ kv += om.get_field(f);
+ kv += '\n';
+ if(co==string::npos) break;
+ p = co+1;
+ }
+ const secret_t& secret = assoc->secret();
+ const EVP_MD *evpmd;
+ const string& at = assoc->assoc_type();
+ if(at=="HMAC-SHA256")
+ evpmd = EVP_sha256();
+ else if(at=="HMAC-SHA1")
+ evpmd = EVP_sha1();
+ else
+ throw unsupported(OPKELE_CP_ "unknown association type");
+ unsigned int md_len = 0;
+ unsigned char *md = HMAC(evpmd,
+ &(secret.front()),secret.size(),
+ (const unsigned char*)kv.data(),kv.length(),
+ 0,&md_len);
+ return encode_base64(md,md_len);
+ }
+
}
}