summaryrefslogtreecommitdiffabout
path: root/lib
Unidiff
Diffstat (limited to 'lib') (more/less context) (ignore whitespace changes)
-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
4 files changed, 4 insertions, 0 deletions
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,72 +1,73 @@
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 }
57 void basic_OP::set_claimed_id(const string& c) { 58 void basic_OP::set_claimed_id(const string& c) {
58 claimed_id = c; 59 claimed_id = c;
59 } 60 }
60 61
61 basic_openid_message& basic_OP::associate( 62 basic_openid_message& basic_OP::associate(
62 basic_openid_message& oum, 63 basic_openid_message& oum,
63 const basic_openid_message& inm) try { 64 const basic_openid_message& inm) try {
64 assert(inm.get_field("mode")=="associate"); 65 assert(inm.get_field("mode")=="associate");
65 util::dh_t dh; 66 util::dh_t dh;
66 util::bignum_t c_pub; 67 util::bignum_t c_pub;
67 unsigned char key_digest[SHA256_DIGEST_LENGTH]; 68 unsigned char key_digest[SHA256_DIGEST_LENGTH];
68 size_t d_len = 0; 69 size_t d_len = 0;
69 string sts = inm.get_field("session_type"); 70 string sts = inm.get_field("session_type");
70 string ats = inm.get_field("assoc_type"); 71 string ats = inm.get_field("assoc_type");
71 if(sts=="DH-SHA1" || sts=="DH-SHA256") { 72 if(sts=="DH-SHA1" || sts=="DH-SHA256") {
72 if(!(dh = DH_new())) 73 if(!(dh = DH_new()))
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,72 +1,73 @@
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
57 58
58 assoc_t basic_RP::associate(const string& OP) { 59 assoc_t basic_RP::associate(const string& OP) {
59 util::dh_t dh = DH_new(); 60 util::dh_t dh = DH_new();
60 if(!dh) 61 if(!dh)
61 throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); 62 throw exception_openssl(OPKELE_CP_ "failed to DH_new()");
62 dh->p = util::dec_to_bignum(data::_default_p); 63 dh->p = util::dec_to_bignum(data::_default_p);
63 dh->g = util::dec_to_bignum(data::_default_g); 64 dh->g = util::dec_to_bignum(data::_default_g);
64 if(!DH_generate_key(dh)) 65 if(!DH_generate_key(dh))
65 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); 66 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()");
66 openid_message_t req; 67 openid_message_t req;
67 req.set_field("ns",OIURI_OPENID20); 68 req.set_field("ns",OIURI_OPENID20);
68 req.set_field("mode","associate"); 69 req.set_field("mode","associate");
69 req.set_field("dh_modulus",util::bignum_to_base64(dh->p)); 70 req.set_field("dh_modulus",util::bignum_to_base64(dh->p));
70 req.set_field("dh_gen",util::bignum_to_base64(dh->g)); 71 req.set_field("dh_gen",util::bignum_to_base64(dh->g));
71 req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key)); 72 req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key));
72 openid_message_t res; 73 openid_message_t res;
diff --git a/lib/consumer.cc b/lib/consumer.cc
index ebda262..801496e 100644
--- a/lib/consumer.cc
+++ b/lib/consumer.cc
@@ -1,68 +1,69 @@
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); }
53 54
54 pcre_t& operator=(pcre *p) { if(_p) (*pcre_free)(_p); _p=p; return *this; } 55 pcre_t& operator=(pcre *p) { if(_p) (*pcre_free)(_p); _p=p; return *this; }
55 56
56 operator const pcre*(void) const { return _p; } 57 operator const pcre*(void) const { return _p; }
57 operator pcre*(void) { return _p; } 58 operator pcre*(void) { return _p; }
58 59
59 int exec(const string& s,pcre_matches_t& m) { 60 int exec(const string& s,pcre_matches_t& m) {
60 if(!_p) 61 if(!_p)
61 throw internal_error(OPKELE_CP_ "Trying to execute absent regexp"); 62 throw internal_error(OPKELE_CP_ "Trying to execute absent regexp");
62 return pcre_exec(_p,NULL,s.c_str(),s.length(),0,0,m._ov,m._s); 63 return pcre_exec(_p,NULL,s.c_str(),s.length(),0,0,m._ov,m._s);
63 } 64 }
64 }; 65 };
65 66
66 assoc_t consumer_t::associate(const string& server) { 67 assoc_t consumer_t::associate(const string& server) {
67 util::dh_t dh = DH_new(); 68 util::dh_t dh = DH_new();
68 if(!dh) 69 if(!dh)
diff --git a/lib/server.cc b/lib/server.cc
index 776f1ae..0dea1eb 100644
--- a/lib/server.cc
+++ b/lib/server.cc
@@ -1,69 +1,70 @@
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();
54 /* TODO: eventually remove deprecated stuff */ 55 /* TODO: eventually remove deprecated stuff */
55 pout["issued"] = util::time_to_w3c(now); 56 pout["issued"] = util::time_to_w3c(now);
56 pout["expiry"] = util::time_to_w3c(now+assoc->expires_in()); 57 pout["expiry"] = util::time_to_w3c(now+assoc->expires_in());
57 pout["expires_in"] = util::long_to_string(assoc->expires_in()); 58 pout["expires_in"] = util::long_to_string(assoc->expires_in());
58 secret_t secret = assoc->secret(); 59 secret_t secret = assoc->secret();
59 switch(st) { 60 switch(st) {
60 case sess_dh_sha1: 61 case sess_dh_sha1:
61 pout["session_type"] = "DH-SHA1"; 62 pout["session_type"] = "DH-SHA1";
62 pout["dh_server_public"] = util::bignum_to_base64(dh->pub_key); 63 pout["dh_server_public"] = util::bignum_to_base64(dh->pub_key);
63 secret.enxor_to_base64(key_sha1,pout["enc_mac_key"]); 64 secret.enxor_to_base64(key_sha1,pout["enc_mac_key"]);
64 break; 65 break;
65 default: 66 default:
66 secret.to_base64(pout["mac_key"]); 67 secret.to_base64(pout["mac_key"]);
67 break; 68 break;
68 } 69 }
69 } 70 }