summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--lib/basic_rp.cc9
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/basic_rp.cc b/lib/basic_rp.cc
index 763a391..2da8416 100644
--- a/lib/basic_rp.cc
+++ b/lib/basic_rp.cc
@@ -4,37 +4,40 @@
4#include <opkele/exception.h> 4#include <opkele/exception.h>
5#include <opkele/uris.h> 5#include <opkele/uris.h>
6#include <opkele/data.h> 6#include <opkele/data.h>
7#include <opkele/util.h> 7#include <opkele/util.h>
8#include <opkele/curl.h> 8#include <opkele/curl.h>
9 9
10namespace opkele { 10namespace opkele {
11 11
12 static void dh_get_secret( 12 static void dh_get_secret(
13 secret_t& secret, const basic_openid_message& om, 13 secret_t& secret, const basic_openid_message& om,
14 const char *exp_assoc, const char *exp_sess, 14 const char *exp_assoc, const char *exp_sess,
15 util::dh_t& dh, 15 util::dh_t& dh,
16 size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*) ) try { 16 size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*),
17 size_t exp_s_len) try {
17 if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess) 18 if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess)
18 throw bad_input(OPKELE_CP_ "Unexpected associate response"); 19 throw bad_input(OPKELE_CP_ "Unexpected associate response");
19 util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public")); 20 util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public"));
20 vector<unsigned char> ck(DH_size(dh)+1); 21 vector<unsigned char> ck(DH_size(dh)+1);
21 unsigned char *ckptr = &(ck.front())+1; 22 unsigned char *ckptr = &(ck.front())+1;
22 int cklen = DH_compute_key(ckptr,s_pub,dh); 23 int cklen = DH_compute_key(ckptr,s_pub,dh);
23 if(cklen<0) 24 if(cklen<0)
24 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); 25 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()");
25 if(cklen && (*ckptr)&0x80) { 26 if(cklen && (*ckptr)&0x80) {
26 (*(--ckptr))=0; ++cklen; } 27 (*(--ckptr))=0; ++cklen; }
27 unsigned char key_digest[d_len]; 28 unsigned char key_digest[d_len];
28 secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key")); 29 secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key"));
30 if(secret.size()!=exp_s_len)
31 throw bad_input(OPKELE_CP_ "Secret length isn't consistent with association type");
29 }catch(opkele::failed_lookup& ofl) { 32 }catch(opkele::failed_lookup& ofl) {
30 throw bad_input(OPKELE_CP_ "Incoherent response from OP"); 33 throw bad_input(OPKELE_CP_ "Incoherent response from OP");
31 } OPKELE_RETHROW 34 } OPKELE_RETHROW
32 35
33 static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) { 36 static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) {
34 util::curl_pick_t curl = util::curl_pick_t::easy_init(); 37 util::curl_pick_t curl = util::curl_pick_t::easy_init();
35 if(!curl) 38 if(!curl)
36 throw exception_curl(OPKELE_CP_ "failed to initialize curl"); 39 throw exception_curl(OPKELE_CP_ "failed to initialize curl");
37 string request = inm.query_string(); 40 string request = inm.query_string();
38 CURLcode r; 41 CURLcode r;
39 (r=curl.misc_sets()) 42 (r=curl.misc_sets())
40 || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str())) 43 || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str()))
@@ -64,34 +67,34 @@ namespace opkele {
64 req.set_field("dh_modulus",util::bignum_to_base64(dh->p)); 67 req.set_field("dh_modulus",util::bignum_to_base64(dh->p));
65 req.set_field("dh_gen",util::bignum_to_base64(dh->g)); 68 req.set_field("dh_gen",util::bignum_to_base64(dh->g));
66 req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key)); 69 req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key));
67 openid_message_t res; 70 openid_message_t res;
68 req.set_field("assoc_type","HMAC-SHA256"); 71 req.set_field("assoc_type","HMAC-SHA256");
69 req.set_field("session_type","DH-SHA256"); 72 req.set_field("session_type","DH-SHA256");
70 secret_t secret; 73 secret_t secret;
71 int expires_in; 74 int expires_in;
72 try { 75 try {
73 direct_request(res,req,OP); 76 direct_request(res,req,OP);
74 dh_get_secret( secret, res, 77 dh_get_secret( secret, res,
75 "HMAC-SHA256", "DH-SHA256", 78 "HMAC-SHA256", "DH-SHA256",
76 dh, SHA256_DIGEST_LENGTH, SHA256 ); 79 dh, SHA256_DIGEST_LENGTH, SHA256, SHA256_DIGEST_LENGTH );
77 expires_in = util::string_to_long(res.get_field("expires_in")); 80 expires_in = util::string_to_long(res.get_field("expires_in"));
78 }catch(exception& e) { 81 }catch(exception& e) {
79 try { 82 try {
80 req.set_field("assoc_type","HMAC-SHA1"); 83 req.set_field("assoc_type","HMAC-SHA1");
81 req.set_field("session_type","DH-SHA1"); 84 req.set_field("session_type","DH-SHA1");
82 direct_request(res,req,OP); 85 direct_request(res,req,OP);
83 dh_get_secret( secret, res, 86 dh_get_secret( secret, res,
84 "HMAC-SHA1", "DH-SHA1", 87 "HMAC-SHA1", "DH-SHA1",
85 dh, SHA_DIGEST_LENGTH, SHA1 ); 88 dh, SHA_DIGEST_LENGTH, SHA1, SHA_DIGEST_LENGTH );
86 expires_in = util::string_to_long(res.get_field("expires_in")); 89 expires_in = util::string_to_long(res.get_field("expires_in"));
87 }catch(bad_input& e) { 90 }catch(bad_input& e) {
88 throw dumb_RP(OPKELE_CP_ "OP failed to supply an association"); 91 throw dumb_RP(OPKELE_CP_ "OP failed to supply an association");
89 } 92 }
90 } 93 }
91 return store_assoc( 94 return store_assoc(
92 OP, res.get_field("assoc_handle"), 95 OP, res.get_field("assoc_handle"),
93 res.get_field("assoc_type"), secret, 96 res.get_field("assoc_type"), secret,
94 expires_in ); 97 expires_in );
95 } 98 }
96 99
97 basic_openid_message& basic_RP::checkid_( 100 basic_openid_message& basic_RP::checkid_(