DeanHere / dotnetopenid

Automatically exported from code.google.com/p/dotnetopenid
0 stars 0 forks source link

Token.Deserialize method throws FormatException #73

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Generate encoded (base64) token with + sign and login to openid server.

What is the expected output? What do you see instead?
Expected successfully login but get exception 'Invalid length for a Base-64
char array.'

What version of the product are you using? On what operating system?
Using DotNetOpenId-2.0.1.8115 on Windows Vista Ultimate x64.

Please provide any additional information below.
Base64 encoding allowing '+' plus sign in data.
HttpUtility.UrlEncode doesn't escape '+' sign, but
HttpUtility.ParseQueryString parsed '+' as space (it's allowed by spec).
So, during decoding token we get wrong base64 encoded token (with space
instead plus sign) and can't decode it (with exception).
Use HttpUtility.UrlPathDecode instead - it escapes plus '+' sign.
Patch is attached.

Original issue reported on code.google.com by greec...@gmail.com on 27 Apr 2008 at 12:34

Attachments:

GoogleCodeExporter commented 9 years ago
Or maybe better use something like this
            foreach (var p in args) {
                sb.Append(HttpUtility.UrlEncode(p.Key).Replace("+", "%2B"));
                sb.Append('=');
                sb.Append(HttpUtility.UrlEncode(p.Value).Replace("+", "%2B"));
                sb.Append('&');
            }

Original comment by greec...@gmail.com on 27 Apr 2008 at 1:16

GoogleCodeExporter commented 9 years ago
Nope, both decisions have some exceptions sometimes.
First doesn't escape symbols after '?' sign in url (i.e. in return url).
Second sometimes failed during checking signature.
Currently it's enough to use HttpServerUtility.UrlTokenDecode &
HttpServerUtility.UrlTokenEncode in Token class instead 
Convert.FromBase64String &
Convert.ToBase64String. It's enough for my OpenIВ provider.
I am not sure about others base64-encoded fields - but never get plus sign in 
them.

Original comment by derigel on 27 Apr 2008 at 2:55

GoogleCodeExporter commented 9 years ago
Great report.  If you have any more ideas for encoding please shoot them my 
way. 
I'll look for a solution as well.

Original comment by andrewar...@gmail.com on 27 Apr 2008 at 3:17

GoogleCodeExporter commented 9 years ago
Still investigating, but I found that 
[System.Web.HttpUtility]::UrlEncode("a+b") -> "a%2bb"
[System.Web.HttpUtility]::UrlDecode("a%2bb") -> "a+b"
So it looks like round-tripping is correct as far as the .NET methods are 
concerned.
 I'll keep investigating OpenID's use of these to see where the problem lies.

Original comment by andrewar...@gmail.com on 27 Apr 2008 at 8:56

GoogleCodeExporter commented 9 years ago
I can't seem to find the problem anywhere.  Can you send a stack trace to the
exception that is thrown?

Original comment by andrewar...@gmail.com on 27 Apr 2008 at 9:18

GoogleCodeExporter commented 9 years ago
This is so bizzare.  I'm starting to get the exception now, several times in a 
row. 
It's erratic, but I wonder why I've never seen it before in the unit tests.  I'm
drilling into it more now.

Thanks for the report.

Original comment by andrewar...@gmail.com on 28 Apr 2008 at 3:03

GoogleCodeExporter commented 9 years ago
Ok, so the culprit is the 
RelyingParty.AuthenticationRequest.RedirectToProviderUrl
property getter, which has the following line:
qsArgs.Add(protocol.openid.return_to, returnToBuilder.Uri.ToString());
The UriBuilder.Uri.ToString() method call unescapes the %2b back to a + sign.
Apparently Uri.AbsoluteUri and Uri.ToString() are NOT the same thing, as 
AbsoluteUri
does NOT unescape the + sign.  So the fix is simple and straightforward.  

Just gotta write a unit test for it and I'll check this in.

Original comment by andrewar...@gmail.com on 28 Apr 2008 at 3:20

GoogleCodeExporter commented 9 years ago
This is fixed in the master, 2.0 and 2.1 branches now.  Will appear in 2.0.2 and
2.1.1 versions.  

Original comment by andrewar...@gmail.com on 28 Apr 2008 at 6:12

GoogleCodeExporter commented 9 years ago
Oh, and FYI it is not a bug in the 1.0 branch.

Original comment by andrewar...@gmail.com on 28 Apr 2008 at 6:12

GoogleCodeExporter commented 9 years ago
First of, thanks for the great work.

Using DotNetOpenId.dll (tried both 2.1.2.8149 & 2.2.0.8152), I ran into the 
exact
same issue described here.
As the issue is already marked as Closed for these versions, it might just be 
me.
Also, running the Sample solutions, (for both versions) everything ran 
absolutely
perfect.

I just can't seem to make it work within my code...
Any help would be appreciated.
The Request URL below does show a '+' sign. The return_to in the same URL 
however has
it escaped.
Again, it might just be me!

Thanks.

-----------------------------------------------------------
Error: Invalid length for a Base-64 char array.
 at System.Convert.FromBase64String(String s)
 at DotNetOpenId.RelyingParty.Token.Deserialize(String token, INonceStore store)
 at DotNetOpenId.RelyingParty.AuthenticationResponse.Parse(IDictionary`2 query,
IRelyingPartyApplicationStore store, Uri requestUrl)
 at DotNetOpenId.RelyingParty.OpenIdRelyingParty.get_Response()
 at DotNetOpenId.RelyingParty.OpenIdTextBox.OnLoad(EventArgs e)
 at System.Web.UI.Control.LoadRecursive()
 at System.Web.UI.Control.LoadRecursive()
 at System.Web.UI.Control.LoadRecursive()
 at System.Web.UI.Control.LoadRecursive()
 at System.Web.UI.Control.LoadRecursive()
 at System.Web.UI.Control.LoadRecursive()
 at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,
Boolean includeStagesAfterAsyncPoint) 
-----------------------------------------------------------
Request URL: 
http://localhost:3801/um/OpenId.aspx
?token=Ebg4rtTE0AJlNt+84AWV49oCx2AHRQl0he6Kyihm7kNodHRwOi8vaW5mb3JuYS5teW9wZW5pZ
C5jb20vDQpodHRwOi8vaW5mb3JuYS5teW9wZW5pZC5jb20vDQpodHRwOi8vd3d3Lm15b3BlbmlkLmNvb
S9zZXJ2ZXINCjIuMA0K
&openid.assoc_handle={HMAC-SHA256}{4849f489}{yxbW1A==}
&openid.claimed_id=http://xyz.myopenid.com/
&openid.identity=http://xyz.myopenid.com/
&openid.mode=id_res
&openid.ns=http://specs.openid.net/auth/2.0
&openid.ns.sreg=http://openid.net/extensions/sreg/1.1
&openid.op_endpoint=http://myopenid.com/server
&openid.response_nonce=2008-06-07T02:38:09ZKPn2qm
&openid.return_to=http://localhost:3801/um/OpenId.aspx?token=Ebg4rtTE0AJlNt%252b
84AWV49oCx2AHRQl0he6Kyihm7kNodHRwOi8vaW5mb3JuYS5teW9wZW5pZC5jb20vDQpodHRwOi8vaW5
mb3JuYS5teW9wZW5pZC5jb20vDQpodHRwOi8vd3d3Lm15b3BlbmlkLmNvbS9zZXJ2ZXINCjIuMA0K
&openid.sig=687Oj6aq8N+8Jy5AG34Owg30G/t7rIVDbDiakRUEeW8=
&openid.signed=assoc_handle,claimed_id,identity,mode,ns,ns.sreg,op_endpoint,resp
onse_nonce,return_to,signed,sreg.email
&openid.sreg.email=xyz@example.com 
-----------------------------------------------------------

Original comment by CoNo...@gmail.com on 7 Jun 2008 at 3:03

GoogleCodeExporter commented 9 years ago
CoNotTS, Can you tell me how you produced the URL that you copied in your 
comment? 
It's not just the + sign.  All the values are decoded here, so I want to know 
what
you used to spit this out.  Did you copy the URL from the browser URL box?  Did 
you
use Uri.ToString() somewhere in your web site?  Or perhaps you got this from a 
trace
message?
(not an interrogation... just possibilities)
Thanks for the report.  I'll investigate as soon as you can answer this.

Original comment by andrewar...@gmail.com on 7 Jun 2008 at 4:28

GoogleCodeExporter commented 9 years ago
Yes, all of it did in fact come from the browser URL box.
So, I have the OpenIdLogin control on a page. I put in the OpenId, click Login,
authenticate on the provider's site. This is the URL in my browser when it 
comes back
to my page.
(I put the line-breaks just to see what I was getting back)

Thanks.

Original comment by CoNo...@gmail.com on 7 Jun 2008 at 4:54

GoogleCodeExporter commented 9 years ago
Hmmm.. Can you tell me any more hints about what might be unique in your 
situation? 
When I use the relying party sample, I get a fully encoded URL back from
myopenid.com.  It sounds like the samples work for you as well, but another site
you've dropped the control into doesn't.  Any idea what your site might be 
doing to
modify the URLs?  I can't think of why the URL would not be encoded from 
myopenid.com
from anything dotnetopenid might send them.

Original comment by andrewar...@gmail.com on 7 Jun 2008 at 5:19

GoogleCodeExporter commented 9 years ago
I am obviously doing something different/wrong here and am taking another look 
at my
setup.
I'll update with any findings.

Meanwhile, playing with the samples a little more, I saw a decoded URL there 
too!
I can bet this never happened till just now. And can't seem to reproduce it 
either.
If it helps:
* The URL box had pretty much the same URL as was turning up in my site
* The message was "Login failed: The signature verification failed"

I am going to take a break now. :)

Original comment by CoNo...@gmail.com on 7 Jun 2008 at 4:20