summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--include/Makefile.am3
-rw-r--r--include/opkele/util-internal.h92
-rw-r--r--include/opkele/util.h92
-rw-r--r--lib/basic_op.cc1
-rw-r--r--lib/basic_rp.cc1
-rw-r--r--lib/consumer.cc1
-rw-r--r--lib/server.cc1
-rw-r--r--test/idiscover.cc1
8 files changed, 110 insertions, 82 deletions
diff --git a/include/Makefile.am b/include/Makefile.am
index 9f5982c..f842bb9 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,32 +1,33 @@
1NODIST_HEADERS_ = \ 1NODIST_HEADERS_ = \
2 opkele/acconfig.h \ 2 opkele/acconfig.h \
3 opkele/tr1-mem.h 3 opkele/tr1-mem.h
4 4
5nobase_include_HEADERS = \ 5nobase_include_HEADERS = \
6 opkele/opkele-config.h \ 6 opkele/opkele-config.h \
7 opkele/types.h \ 7 opkele/types.h \
8 opkele/association.h \ 8 opkele/association.h \
9 opkele/exception.h \ 9 opkele/exception.h \
10 opkele/server.h \ 10 opkele/server.h \
11 opkele/consumer.h \ 11 opkele/consumer.h \
12 opkele/extension.h \ 12 opkele/extension.h \
13 opkele/sreg.h \ 13 opkele/sreg.h \
14 opkele/extension_chain.h \ 14 opkele/extension_chain.h \
15 opkele/xconsumer.h \ 15 opkele/xconsumer.h \
16 opkele/xserver.h \ 16 opkele/xserver.h \
17 opkele/uris.h \ 17 opkele/uris.h \
18 opkele/tr1-mem.h \ 18 opkele/tr1-mem.h \
19 opkele/basic_rp.h opkele/prequeue_rp.h \ 19 opkele/basic_rp.h opkele/prequeue_rp.h \
20 opkele/iterator.h \ 20 opkele/iterator.h \
21 opkele/basic_op.h opkele/verify_op.h \ 21 opkele/basic_op.h opkele/verify_op.h \
22 opkele/util.h \
22 ${NODIST_HEADERS_} 23 ${NODIST_HEADERS_}
23 24
24noinst_HEADERS = \ 25noinst_HEADERS = \
25 opkele/data.h \ 26 opkele/data.h \
26 opkele/curl.h opkele/expat.h opkele/tidy.h \ 27 opkele/curl.h opkele/expat.h opkele/tidy.h \
27 opkele/util.h \ 28 opkele/util-internal.h \
28 opkele/debug.h \ 29 opkele/debug.h \
29 opkele/discovery.h 30 opkele/discovery.h
30 31
31dist-hook: 32dist-hook:
32 rm -f $(addprefix ${distdir}/,${NODIST_HEADERS_}) 33 rm -f $(addprefix ${distdir}/,${NODIST_HEADERS_})
diff --git a/include/opkele/util-internal.h b/include/opkele/util-internal.h
new file mode 100644
index 0000000..ec091ce
--- a/dev/null
+++ b/include/opkele/util-internal.h
@@ -0,0 +1,92 @@
1#ifndef __OPKELE_UTIL_INTERNAL_H
2#define __OPKELE_UTIL_INTERNAL_H
3
4#include <openssl/bn.h>
5#include <openssl/dh.h>
6
7namespace opkele {
8 namespace util {
9
10 /**
11 * Convenience class encapsulating SSL BIGNUM object for the purpose of
12 * automatical freeing.
13 */
14 class bignum_t {
15 public:
16 BIGNUM *_bn;
17
18 bignum_t() : _bn(0) { }
19 bignum_t(BIGNUM *bn) : _bn(bn) { }
20 ~bignum_t() throw() { if(_bn) BN_free(_bn); }
21
22 bignum_t& operator=(BIGNUM *bn) { if(_bn) BN_free(_bn); _bn = bn; return *this; }
23
24 operator const BIGNUM*(void) const { return _bn; }
25 operator BIGNUM*(void) { return _bn; }
26 };
27 /**
28 * Convenience clas encapsulating SSL DH object for the purpose of
29 * automatic freeing.
30 */
31 class dh_t {
32 public:
33 DH *_dh;
34
35 dh_t() : _dh(0) { }
36 dh_t(DH *dh) : _dh(dh) { }
37 ~dh_t() throw() { if(_dh) DH_free(_dh); }
38
39 dh_t& operator=(DH *dh) { if(_dh) DH_free(_dh); _dh = dh; return *this; }
40
41 operator const DH*(void) const { return _dh; }
42 operator DH*(void) { return _dh; }
43
44 DH* operator->() { return _dh; }
45 const DH* operator->() const { return _dh; }
46 };
47
48 /**
49 * Convert base64-encoded SSL BIGNUM to internal representation.
50 * @param b64 base64-encoded number
51 * @return SSL BIGNUM
52 * @throw failed_conversion in case of error
53 */
54 BIGNUM *base64_to_bignum(const string& b64);
55 /**
56 * Convert decimal representation to SSL BIGNUM.
57 * @param dec decimal representation
58 * @return resulting BIGNUM
59 * @throw failed_conversion in case of error
60 */
61 BIGNUM *dec_to_bignum(const string& dec);
62 /**
63 * Convert SSL BIGNUM data to base64 encoded string.
64 * @param bn BIGNUM
65 * @return base64encoded string
66 */
67 string bignum_to_base64(const BIGNUM *bn);
68
69 string abi_demangle(const char* mn);
70
71 class change_mode_message_proxy : public basic_openid_message {
72 public:
73 const basic_openid_message& x;
74 const string& mode;
75
76 change_mode_message_proxy(const basic_openid_message& xx,const string& m) : x(xx), mode(m) { }
77
78 bool has_field(const string& n) const { return x.has_field(n); }
79 const string& get_field(const string& n) const {
80 return (n=="mode")?mode:x.get_field(n); }
81 bool has_ns(const string& uri) const {return x.has_ns(uri); }
82 string get_ns(const string& uri) const { return x.get_ns(uri); }
83 fields_iterator fields_begin() const {
84 return x.fields_begin(); }
85 fields_iterator fields_end() const {
86 return x.fields_end(); }
87 };
88
89 }
90}
91
92#endif /* __OPKELE_UTIL_INTERNAL_H */
diff --git a/include/opkele/util.h b/include/opkele/util.h
index bc1a0ea..60955e1 100644
--- a/include/opkele/util.h
+++ b/include/opkele/util.h
@@ -1,184 +1,114 @@
1#ifndef __OPKELE_UTIL_H 1#ifndef __OPKELE_UTIL_H
2#define __OPKELE_UTIL_H 2#define __OPKELE_UTIL_H
3 3
4#include <time.h> 4#include <time.h>
5#include <string> 5#include <string>
6#include <vector> 6#include <vector>
7#include <openssl/bn.h>
8#include <openssl/dh.h>
9#include <opkele/types.h> 7#include <opkele/types.h>
10 8
11namespace opkele { 9namespace opkele {
12 using std::string; 10 using std::string;
13 using std::vector; 11 using std::vector;
14 12
15 /** 13 /**
16 * @brief opkele utils namespace 14 * @brief opkele utils namespace
17 */ 15 */
18 namespace util { 16 namespace util {
19 17
20 /** 18 /**
21 * Convenience class encapsulating SSL BIGNUM object for the purpose of
22 * automatical freeing.
23 */
24 class bignum_t {
25 public:
26 BIGNUM *_bn;
27
28 bignum_t() : _bn(0) { }
29 bignum_t(BIGNUM *bn) : _bn(bn) { }
30 ~bignum_t() throw() { if(_bn) BN_free(_bn); }
31
32 bignum_t& operator=(BIGNUM *bn) { if(_bn) BN_free(_bn); _bn = bn; return *this; }
33
34 operator const BIGNUM*(void) const { return _bn; }
35 operator BIGNUM*(void) { return _bn; }
36 };
37 /**
38 * Convenience clas encapsulating SSL DH object for the purpose of
39 * automatic freeing.
40 */
41 class dh_t {
42 public:
43 DH *_dh;
44
45 dh_t() : _dh(0) { }
46 dh_t(DH *dh) : _dh(dh) { }
47 ~dh_t() throw() { if(_dh) DH_free(_dh); }
48
49 dh_t& operator=(DH *dh) { if(_dh) DH_free(_dh); _dh = dh; return *this; }
50
51 operator const DH*(void) const { return _dh; }
52 operator DH*(void) { return _dh; }
53
54 DH* operator->() { return _dh; }
55 const DH* operator->() const { return _dh; }
56 };
57
58 /**
59 * Convert base64-encoded SSL BIGNUM to internal representation.
60 * @param b64 base64-encoded number
61 * @return SSL BIGNUM
62 * @throw failed_conversion in case of error
63 */
64 BIGNUM *base64_to_bignum(const string& b64);
65 /**
66 * Convert decimal representation to SSL BIGNUM.
67 * @param dec decimal representation
68 * @return resulting BIGNUM
69 * @throw failed_conversion in case of error
70 */
71 BIGNUM *dec_to_bignum(const string& dec);
72 /**
73 * Convert SSL BIGNUM data to base64 encoded string.
74 * @param bn BIGNUM
75 * @return base64encoded string
76 */
77 string bignum_to_base64(const BIGNUM *bn);
78
79 /**
80 * Convert internal time representation to w3c format 19 * Convert internal time representation to w3c format
81 * @param t internal representation 20 * @param t internal representation
82 * @return w3c time 21 * @return w3c time
83 * @throw failed_conversion in case of error 22 * @throw failed_conversion in case of error
84 */ 23 */
85 string time_to_w3c(time_t t); 24 string time_to_w3c(time_t t);
86 /** 25 /**
87 * Convert W3C time representation to internal time_t 26 * Convert W3C time representation to internal time_t
88 * @param w w3c representation 27 * @param w w3c representation
89 * @return converted time 28 * @return converted time
90 * @throw failed_conversion in case of error 29 * @throw failed_conversion in case of error
91 */ 30 */
92 time_t w3c_to_time(const string& w); 31 time_t w3c_to_time(const string& w);
93 32
94 /** 33 /**
95 * Encode string to the representation suitable for using in URL. 34 * Encode string to the representation suitable for using in URL.
96 * @param str string to encode 35 * @param str string to encode
97 * @return encoded string 36 * @return encoded string
98 * @throw failed_conversion in case of failure 37 * @throw failed_conversion in case of failure
99 */ 38 */
100 string url_encode(const string& str); 39 string url_encode(const string& str);
101 40
102 /** 41 /**
103 * Make string suitable for using as x(ht)ml attribute. 42 * Make string suitable for using as x(ht)ml attribute.
104 * @param str string to escape 43 * @param str string to escape
105 * @return escaped string 44 * @return escaped string
106 */ 45 */
107 string attr_escape(const string& str); 46 string attr_escape(const string& str);
108 47
109 /** 48 /**
110 * Convert number to string 49 * Convert number to string
111 * @param l number 50 * @param l number
112 * @return string representation 51 * @return string representation
113 * @throw failed_conversion in case of failure 52 * @throw failed_conversion in case of failure
114 */ 53 */
115 string long_to_string(long l); 54 string long_to_string(long l);
116 /** 55 /**
117 * Convert string to number 56 * Convert string to number
118 * @param s string, containing the number 57 * @param s string, containing the number
119 * @return the number 58 * @return the number
120 * @throw failed_conversion in case of failure 59 * @throw failed_conversion in case of failure
121 */ 60 */
122 long string_to_long(const string& s); 61 long string_to_long(const string& s);
123 62
124 /** 63 /**
125 * Encode binary data using base64. 64 * Encode binary data using base64.
126 * @param data pointer to binary data 65 * @param data pointer to binary data
127 * @param length length of data 66 * @param length length of data
128 * @return encoded data 67 * @return encoded data
129 */ 68 */
130 string encode_base64(const void *data,size_t length); 69 string encode_base64(const void *data,size_t length);
131 /** 70 /**
132 * Decode binary data from base64 representation. 71 * Decode binary data from base64 representation.
133 * @param data base64-encoded data 72 * @param data base64-encoded data
134 * @param rv container for decoded binary 73 * @param rv container for decoded binary
135 */ 74 */
136 void decode_base64(const string& data,vector<unsigned char>& rv); 75 void decode_base64(const string& data,vector<unsigned char>& rv);
137 76
138 /** 77 /**
139 * Normalize http(s) URI according to RFC3986, section 6. URI is 78 * Normalize http(s) URI according to RFC3986, section 6. URI is
140 * expected to have scheme: in front of it. 79 * expected to have scheme: in front of it.
141 * @param uri URI 80 * @param uri URI
142 * @return normalized URI 81 * @return normalized URI
143 * @throw not_implemented in case of non-httpi(s) URI 82 * @throw not_implemented in case of non-httpi(s) URI
144 * @throw bad_input in case of malformed URI 83 * @throw bad_input in case of malformed URI
145 */ 84 */
146 string rfc_3986_normalize_uri(const string& uri); 85 string rfc_3986_normalize_uri(const string& uri);
147 86
148 /** 87 /**
149 * Match URI against realm 88 * Match URI against realm
150 * @param uri URI to match 89 * @param uri URI to match
151 * @param realm realm to match against 90 * @param realm realm to match against
152 * @return true if URI matches realm 91 * @return true if URI matches realm
153 */ 92 */
154 bool uri_matches_realm(const string& uri,const string& realm); 93 bool uri_matches_realm(const string& uri,const string& realm);
155 94
95 /**
96 * Strip fragment part from URI
97 * @param uri input/output parameter containing the URI
98 * @return reference to uri
99 */
156 string& strip_uri_fragment_part(string& uri); 100 string& strip_uri_fragment_part(string& uri);
157 101
158 string abi_demangle(const char* mn); 102 /**
159 103 * Calculate signature and encode it using base64
104 * @param assoc association being used for signing
105 * @param om openid message
106 * @return base64 representation of the signature
107 */
160 string base64_signature(const assoc_t& assoc,const basic_openid_message& om); 108 string base64_signature(const assoc_t& assoc,const basic_openid_message& om);
161 109
162 class change_mode_message_proxy : public basic_openid_message {
163 public:
164 const basic_openid_message& x;
165 const string& mode;
166
167 change_mode_message_proxy(const basic_openid_message& xx,const string& m) : x(xx), mode(m) { }
168
169 bool has_field(const string& n) const { return x.has_field(n); }
170 const string& get_field(const string& n) const {
171 return (n=="mode")?mode:x.get_field(n); }
172 bool has_ns(const string& uri) const {return x.has_ns(uri); }
173 string get_ns(const string& uri) const { return x.get_ns(uri); }
174 fields_iterator fields_begin() const {
175 return x.fields_begin(); }
176 fields_iterator fields_end() const {
177 return x.fields_end(); }
178 };
179
180 } 110 }
181 111
182} 112}
183 113
184#endif /* __OPKELE_UTIL_H */ 114#endif /* __OPKELE_UTIL_H */
diff --git a/lib/basic_op.cc b/lib/basic_op.cc
index c247493..fa659ac 100644
--- a/lib/basic_op.cc
+++ b/lib/basic_op.cc
@@ -1,56 +1,57 @@
1#include <time.h> 1#include <time.h>
2#include <cassert> 2#include <cassert>
3#include <openssl/sha.h> 3#include <openssl/sha.h>
4#include <openssl/hmac.h> 4#include <openssl/hmac.h>
5#include <opkele/data.h> 5#include <opkele/data.h>
6#include <opkele/basic_op.h> 6#include <opkele/basic_op.h>
7#include <opkele/exception.h> 7#include <opkele/exception.h>
8#include <opkele/util.h> 8#include <opkele/util.h>
9#include <opkele/util-internal.h>
9#include <opkele/uris.h> 10#include <opkele/uris.h>
10 11
11namespace opkele { 12namespace opkele {
12 13
13 void basic_OP::reset_vars() { 14 void basic_OP::reset_vars() {
14 assoc.reset(); 15 assoc.reset();
15 return_to.clear(); realm.clear(); 16 return_to.clear(); realm.clear();
16 claimed_id.clear(); identity.clear(); 17 claimed_id.clear(); identity.clear();
17 invalidate_handle.clear(); 18 invalidate_handle.clear();
18 } 19 }
19 20
20 bool basic_OP::has_return_to() const { 21 bool basic_OP::has_return_to() const {
21 return !return_to.empty(); 22 return !return_to.empty();
22 } 23 }
23 const string& basic_OP::get_return_to() const { 24 const string& basic_OP::get_return_to() const {
24 if(return_to.empty()) 25 if(return_to.empty())
25 throw no_return_to(OPKELE_CP_ "No return_to URL provided with request"); 26 throw no_return_to(OPKELE_CP_ "No return_to URL provided with request");
26 return return_to; 27 return return_to;
27 } 28 }
28 29
29 const string& basic_OP::get_realm() const { 30 const string& basic_OP::get_realm() const {
30 assert(!realm.empty()); 31 assert(!realm.empty());
31 return realm; 32 return realm;
32 } 33 }
33 34
34 bool basic_OP::has_identity() const { 35 bool basic_OP::has_identity() const {
35 return !identity.empty(); 36 return !identity.empty();
36 } 37 }
37 const string& basic_OP::get_claimed_id() const { 38 const string& basic_OP::get_claimed_id() const {
38 if(claimed_id.empty()) 39 if(claimed_id.empty())
39 throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request"); 40 throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request");
40 assert(!identity.empty()); 41 assert(!identity.empty());
41 return claimed_id; 42 return claimed_id;
42 } 43 }
43 const string& basic_OP::get_identity() const { 44 const string& basic_OP::get_identity() const {
44 if(identity.empty()) 45 if(identity.empty())
45 throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request"); 46 throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request");
46 assert(!claimed_id.empty()); 47 assert(!claimed_id.empty());
47 return identity; 48 return identity;
48 } 49 }
49 50
50 bool basic_OP::is_id_select() const { 51 bool basic_OP::is_id_select() const {
51 return identity==IDURI_SELECT20; 52 return identity==IDURI_SELECT20;
52 } 53 }
53 54
54 void basic_OP::select_identity(const string& c,const string& i) { 55 void basic_OP::select_identity(const string& c,const string& i) {
55 claimed_id = c; identity = i; 56 claimed_id = c; identity = i;
56 } 57 }
diff --git a/lib/basic_rp.cc b/lib/basic_rp.cc
index a0ad130..e65d9fb 100644
--- a/lib/basic_rp.cc
+++ b/lib/basic_rp.cc
@@ -1,56 +1,57 @@
1#include <cassert> 1#include <cassert>
2#include <openssl/sha.h> 2#include <openssl/sha.h>
3#include <openssl/hmac.h> 3#include <openssl/hmac.h>
4#include <opkele/basic_rp.h> 4#include <opkele/basic_rp.h>
5#include <opkele/exception.h> 5#include <opkele/exception.h>
6#include <opkele/uris.h> 6#include <opkele/uris.h>
7#include <opkele/data.h> 7#include <opkele/data.h>
8#include <opkele/util.h> 8#include <opkele/util.h>
9#include <opkele/util-internal.h>
9#include <opkele/curl.h> 10#include <opkele/curl.h>
10 11
11namespace opkele { 12namespace opkele {
12 13
13 static void dh_get_secret( 14 static void dh_get_secret(
14 secret_t& secret, const basic_openid_message& om, 15 secret_t& secret, const basic_openid_message& om,
15 const char *exp_assoc, const char *exp_sess, 16 const char *exp_assoc, const char *exp_sess,
16 util::dh_t& dh, 17 util::dh_t& dh,
17 size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*), 18 size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*),
18 size_t exp_s_len) try { 19 size_t exp_s_len) try {
19 if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess) 20 if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess)
20 throw bad_input(OPKELE_CP_ "Unexpected associate response"); 21 throw bad_input(OPKELE_CP_ "Unexpected associate response");
21 util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public")); 22 util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public"));
22 vector<unsigned char> ck(DH_size(dh)+1); 23 vector<unsigned char> ck(DH_size(dh)+1);
23 unsigned char *ckptr = &(ck.front())+1; 24 unsigned char *ckptr = &(ck.front())+1;
24 int cklen = DH_compute_key(ckptr,s_pub,dh); 25 int cklen = DH_compute_key(ckptr,s_pub,dh);
25 if(cklen<0) 26 if(cklen<0)
26 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); 27 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()");
27 if(cklen && (*ckptr)&0x80) { 28 if(cklen && (*ckptr)&0x80) {
28 (*(--ckptr))=0; ++cklen; } 29 (*(--ckptr))=0; ++cklen; }
29 assert(d_len<=SHA256_DIGEST_LENGTH); 30 assert(d_len<=SHA256_DIGEST_LENGTH);
30 unsigned char key_digest[SHA256_DIGEST_LENGTH]; 31 unsigned char key_digest[SHA256_DIGEST_LENGTH];
31 secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key")); 32 secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key"));
32 if(secret.size()!=exp_s_len) 33 if(secret.size()!=exp_s_len)
33 throw bad_input(OPKELE_CP_ "Secret length isn't consistent with association type"); 34 throw bad_input(OPKELE_CP_ "Secret length isn't consistent with association type");
34 }catch(opkele::failed_lookup& ofl) { 35 }catch(opkele::failed_lookup& ofl) {
35 throw bad_input(OPKELE_CP_ "Incoherent response from OP"); 36 throw bad_input(OPKELE_CP_ "Incoherent response from OP");
36 } OPKELE_RETHROW 37 } OPKELE_RETHROW
37 38
38 static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) { 39 static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) {
39 util::curl_pick_t curl = util::curl_pick_t::easy_init(); 40 util::curl_pick_t curl = util::curl_pick_t::easy_init();
40 if(!curl) 41 if(!curl)
41 throw exception_curl(OPKELE_CP_ "failed to initialize curl"); 42 throw exception_curl(OPKELE_CP_ "failed to initialize curl");
42 string request = inm.query_string(); 43 string request = inm.query_string();
43 CURLcode r; 44 CURLcode r;
44 (r=curl.misc_sets()) 45 (r=curl.misc_sets())
45 || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str())) 46 || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str()))
46 || (r=curl.easy_setopt(CURLOPT_POST,1)) 47 || (r=curl.easy_setopt(CURLOPT_POST,1))
47 || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data())) 48 || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data()))
48 || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length())) 49 || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length()))
49 || (r=curl.set_write()); 50 || (r=curl.set_write());
50 if(r) 51 if(r)
51 throw exception_curl(OPKELE_CP_ "failed to set curly options",r); 52 throw exception_curl(OPKELE_CP_ "failed to set curly options",r);
52 if( (r=curl.easy_perform()) ) 53 if( (r=curl.easy_perform()) )
53 throw exception_curl(OPKELE_CP_ "failed to perform curly request",r); 54 throw exception_curl(OPKELE_CP_ "failed to perform curly request",r);
54 oum.from_keyvalues(curl.response); 55 oum.from_keyvalues(curl.response);
55 } 56 }
56 57
diff --git a/lib/consumer.cc b/lib/consumer.cc
index ebda262..801496e 100644
--- a/lib/consumer.cc
+++ b/lib/consumer.cc
@@ -1,52 +1,53 @@
1#include <algorithm> 1#include <algorithm>
2#include <cassert> 2#include <cassert>
3#include <cstring> 3#include <cstring>
4#include <opkele/util.h> 4#include <opkele/util.h>
5#include <opkele/util-internal.h>
5#include <opkele/curl.h> 6#include <opkele/curl.h>
6#include <opkele/exception.h> 7#include <opkele/exception.h>
7#include <opkele/data.h> 8#include <opkele/data.h>
8#include <opkele/consumer.h> 9#include <opkele/consumer.h>
9#include <openssl/sha.h> 10#include <openssl/sha.h>
10#include <openssl/hmac.h> 11#include <openssl/hmac.h>
11#include <iostream> 12#include <iostream>
12 13
13#include "config.h" 14#include "config.h"
14 15
15#include <pcre.h> 16#include <pcre.h>
16 17
17namespace opkele { 18namespace opkele {
18 using namespace std; 19 using namespace std;
19 using util::curl_t; 20 using util::curl_t;
20 using util::curl_pick_t; 21 using util::curl_pick_t;
21 22
22 class pcre_matches_t { 23 class pcre_matches_t {
23 public: 24 public:
24 int *_ov; 25 int *_ov;
25 int _s; 26 int _s;
26 27
27 pcre_matches_t() : _ov(0), _s(0) { } 28 pcre_matches_t() : _ov(0), _s(0) { }
28 pcre_matches_t(int s) : _ov(0), _s(s) { 29 pcre_matches_t(int s) : _ov(0), _s(s) {
29 if(_s&1) ++_s; 30 if(_s&1) ++_s;
30 _s += _s>>1; 31 _s += _s>>1;
31 _ov = new int[_s]; 32 _ov = new int[_s];
32 } 33 }
33 ~pcre_matches_t() throw() { if(_ov) delete[] _ov; } 34 ~pcre_matches_t() throw() { if(_ov) delete[] _ov; }
34 35
35 int begin(int i) const { return _ov[i<<1]; } 36 int begin(int i) const { return _ov[i<<1]; }
36 int end(int i) const { return _ov[(i<<1)+1]; } 37 int end(int i) const { return _ov[(i<<1)+1]; }
37 int length(int i) const { int t=i<<1; return _ov[t+1]-_ov[t]; } 38 int length(int i) const { int t=i<<1; return _ov[t+1]-_ov[t]; }
38 }; 39 };
39 40
40 class pcre_t { 41 class pcre_t {
41 public: 42 public:
42 pcre *_p; 43 pcre *_p;
43 44
44 pcre_t() : _p(0) { } 45 pcre_t() : _p(0) { }
45 pcre_t(pcre *p) : _p(p) { } 46 pcre_t(pcre *p) : _p(p) { }
46 pcre_t(const char *re,int opts) : _p(0) { 47 pcre_t(const char *re,int opts) : _p(0) {
47 static const char *errptr; static int erroffset; 48 static const char *errptr; static int erroffset;
48 _p = pcre_compile(re,opts,&errptr,&erroffset,NULL); 49 _p = pcre_compile(re,opts,&errptr,&erroffset,NULL);
49 if(!_p) 50 if(!_p)
50 throw internal_error(OPKELE_CP_ string("Failed to compile regexp: ")+errptr); 51 throw internal_error(OPKELE_CP_ string("Failed to compile regexp: ")+errptr);
51 } 52 }
52 ~pcre_t() throw() { if(_p) (*pcre_free)(_p); } 53 ~pcre_t() throw() { if(_p) (*pcre_free)(_p); }
diff --git a/lib/server.cc b/lib/server.cc
index 776f1ae..0dea1eb 100644
--- a/lib/server.cc
+++ b/lib/server.cc
@@ -1,53 +1,54 @@
1#include <cstring> 1#include <cstring>
2#include <vector> 2#include <vector>
3#include <openssl/sha.h> 3#include <openssl/sha.h>
4#include <openssl/hmac.h> 4#include <openssl/hmac.h>
5#include <opkele/util.h> 5#include <opkele/util.h>
6#include <opkele/util-internal.h>
6#include <opkele/exception.h> 7#include <opkele/exception.h>
7#include <opkele/server.h> 8#include <opkele/server.h>
8#include <opkele/data.h> 9#include <opkele/data.h>
9 10
10namespace opkele { 11namespace opkele {
11 using namespace std; 12 using namespace std;
12 13
13 void server_t::associate(const params_t& pin,params_t& pout) { 14 void server_t::associate(const params_t& pin,params_t& pout) {
14 util::dh_t dh; 15 util::dh_t dh;
15 util::bignum_t c_pub; 16 util::bignum_t c_pub;
16 unsigned char key_sha1[SHA_DIGEST_LENGTH]; 17 unsigned char key_sha1[SHA_DIGEST_LENGTH];
17 enum { 18 enum {
18 sess_cleartext, 19 sess_cleartext,
19 sess_dh_sha1 20 sess_dh_sha1
20 } st = sess_cleartext; 21 } st = sess_cleartext;
21 if( 22 if(
22 pin.has_param("openid.session_type") 23 pin.has_param("openid.session_type")
23 && pin.get_param("openid.session_type")=="DH-SHA1" ) { 24 && pin.get_param("openid.session_type")=="DH-SHA1" ) {
24 /* TODO: fallback to cleartext in case of exceptions here? */ 25 /* TODO: fallback to cleartext in case of exceptions here? */
25 if(!(dh = DH_new())) 26 if(!(dh = DH_new()))
26 throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); 27 throw exception_openssl(OPKELE_CP_ "failed to DH_new()");
27 c_pub = util::base64_to_bignum(pin.get_param("openid.dh_consumer_public")); 28 c_pub = util::base64_to_bignum(pin.get_param("openid.dh_consumer_public"));
28 if(pin.has_param("openid.dh_modulus")) 29 if(pin.has_param("openid.dh_modulus"))
29 dh->p = util::base64_to_bignum(pin.get_param("openid.dh_modulus")); 30 dh->p = util::base64_to_bignum(pin.get_param("openid.dh_modulus"));
30 else 31 else
31 dh->p = util::dec_to_bignum(data::_default_p); 32 dh->p = util::dec_to_bignum(data::_default_p);
32 if(pin.has_param("openid.dh_gen")) 33 if(pin.has_param("openid.dh_gen"))
33 dh->g = util::base64_to_bignum(pin.get_param("openid.dh_gen")); 34 dh->g = util::base64_to_bignum(pin.get_param("openid.dh_gen"));
34 else 35 else
35 dh->g = util::dec_to_bignum(data::_default_g); 36 dh->g = util::dec_to_bignum(data::_default_g);
36 if(!DH_generate_key(dh)) 37 if(!DH_generate_key(dh))
37 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); 38 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()");
38 vector<unsigned char> ck(DH_size(dh)+1); 39 vector<unsigned char> ck(DH_size(dh)+1);
39 unsigned char *ckptr = &(ck.front())+1; 40 unsigned char *ckptr = &(ck.front())+1;
40 int cklen = DH_compute_key(ckptr,c_pub,dh); 41 int cklen = DH_compute_key(ckptr,c_pub,dh);
41 if(cklen<0) 42 if(cklen<0)
42 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); 43 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()");
43 if(cklen && (*ckptr)&0x80) { 44 if(cklen && (*ckptr)&0x80) {
44 (*(--ckptr)) = 0; ++cklen; 45 (*(--ckptr)) = 0; ++cklen;
45 } 46 }
46 SHA1(ckptr,cklen,key_sha1); 47 SHA1(ckptr,cklen,key_sha1);
47 st = sess_dh_sha1; 48 st = sess_dh_sha1;
48 } 49 }
49 assoc_t assoc = alloc_assoc(mode_associate); 50 assoc_t assoc = alloc_assoc(mode_associate);
50 time_t now = time(0); 51 time_t now = time(0);
51 pout.clear(); 52 pout.clear();
52 pout["assoc_type"] = assoc->assoc_type(); 53 pout["assoc_type"] = assoc->assoc_type();
53 pout["assoc_handle"] = assoc->handle(); 54 pout["assoc_handle"] = assoc->handle();
diff --git a/test/idiscover.cc b/test/idiscover.cc
index 44df9ce..4b1e90c 100644
--- a/test/idiscover.cc
+++ b/test/idiscover.cc
@@ -1,40 +1,41 @@
1#include <iostream> 1#include <iostream>
2#include <stdexcept> 2#include <stdexcept>
3#include <iterator> 3#include <iterator>
4#include <algorithm> 4#include <algorithm>
5using namespace std; 5using namespace std;
6#include <opkele/exception.h> 6#include <opkele/exception.h>
7#include <opkele/discovery.h> 7#include <opkele/discovery.h>
8#include <opkele/util.h> 8#include <opkele/util.h>
9#include <opkele/util-internal.h>
9 10
10namespace opkele { 11namespace opkele {
11 ostream& operator<<(ostream& o,const opkele::openid_endpoint_t& oep) { 12 ostream& operator<<(ostream& o,const opkele::openid_endpoint_t& oep) {
12 o 13 o
13 << " URI: " << oep.uri << endl 14 << " URI: " << oep.uri << endl
14 << " Claimed ID: " << oep.claimed_id << endl 15 << " Claimed ID: " << oep.claimed_id << endl
15 << " Local ID: " << oep.local_id << endl; 16 << " Local ID: " << oep.local_id << endl;
16 return o; 17 return o;
17 } 18 }
18} 19}
19 20
20int main(int argc,char **argv) { 21int main(int argc,char **argv) {
21 try { 22 try {
22 if(argc<2) 23 if(argc<2)
23 throw opkele::exception(OPKELE_CP_ "Please, give me something to resolve"); 24 throw opkele::exception(OPKELE_CP_ "Please, give me something to resolve");
24 for(int a=1;a<argc;++a) { 25 for(int a=1;a<argc;++a) {
25 cout << "==============================================================" << endl 26 cout << "==============================================================" << endl
26 << "User-supplied ID: " << argv[a] << endl 27 << "User-supplied ID: " << argv[a] << endl
27 << "Endpoints:" << endl 28 << "Endpoints:" << endl
28 << " --" << endl; 29 << " --" << endl;
29 string normalized = opkele::idiscover( 30 string normalized = opkele::idiscover(
30 ostream_iterator<opkele::openid_endpoint_t>(cout," --\n") 31 ostream_iterator<opkele::openid_endpoint_t>(cout," --\n")
31 ,argv[a]); 32 ,argv[a]);
32 cout << "Normalized ID: " << normalized << endl; 33 cout << "Normalized ID: " << normalized << endl;
33 } 34 }
34 }catch(exception& e) { 35 }catch(exception& e) {
35 cerr << "oops, caught " << opkele::util::abi_demangle(typeid(e).name()) << endl 36 cerr << "oops, caught " << opkele::util::abi_demangle(typeid(e).name()) << endl
36 << " .what(): " << e.what() << endl; 37 << " .what(): " << e.what() << endl;
37 _exit(1); 38 _exit(1);
38 } 39 }
39 _exit(0); 40 _exit(0);
40} 41}