/// <summary> /// Tests two signatures to see if they match. /// Performs various cross encodings to make sure signature matching is very fuzzy. /// </summary> /// <param name="suppliedSignature"></param> /// <param name="calculatedSignature"></param> /// <returns></returns> private bool OauthSignaturesMatch(string suppliedSignature, string calculatedSignature, string scheme, int signatureStage) { if (false == string.IsNullOrEmpty(calculatedSignature)) { if (suppliedSignature.Equals(calculatedSignature)) { return(true); } if (suppliedSignature.Equals(HttpUtility.UrlEncode(calculatedSignature))) { return(true); } if (suppliedSignature.Equals(OAuthBase.UrlEncode(calculatedSignature))) { return(true); } if (suppliedSignature.Equals(HttpUtility.UrlDecode(calculatedSignature))) { return(true); } } return(false); }
public bool IsValidSignature(string consumerSecret) { int signatureStage = 0; string[] secrets; if (string.IsNullOrEmpty(oauthToken)) { secrets = new string[] { consumerSecret }; } else { secrets = new string[] { consumerSecret, string.Empty }; } foreach (string secret in secrets) { foreach (string scheme in schemes) { Uri origUri = requestUrl; StringBuilder newUrl = new StringBuilder(); newUrl.Append(scheme); newUrl.Append("://"); newUrl.Append(requestUrl.Host); if ((requestUrl.Port != 80) && (requestUrl.Port != 443)) { newUrl.Append(":"); newUrl.Append(requestUrl.Port.ToString()); } newUrl.Append(requestUrl.AbsolutePath); newUrl.Append(requestUrl.Query); Uri newUri = new Uri(newUrl.ToString()); string sig; if (null == oauthToken) { oauthToken = string.Empty; // token may or may not be present } if (null == oauthTokenSecret) { oauthTokenSecret = string.Empty; // tokenSecret may or may not be present } // Try all unencoded first // sig = OAuthBase.GenerateSignature( newUri, oauthConsumerKey, secret, oauthToken, oauthTokenSecret, requestType, oauthTimeStamp, oauthNonce, OAuthBase.SignatureTypes.HMACSHA1, oauthVersion, oauthBodyHash, bodyParams, true, false, false); if (OauthSignaturesMatch(oauthSignature, sig, scheme, signatureStage++)) { return(true); } // Try all encoded consumer key, everything else unencoded // sig = OAuthBase.GenerateSignature( newUri, HttpUtility.UrlEncode(oauthConsumerKey), secret, oauthToken, oauthTokenSecret, requestType, oauthTimeStamp, oauthNonce, OAuthBase.SignatureTypes.HMACSHA1, oauthVersion, oauthBodyHash, bodyParams, true, false, false); if (OauthSignaturesMatch(oauthSignature, sig, scheme, signatureStage++)) { return(true); } // Try with unencoded consumer key since the spec is ambiguous on this point // sig = OAuthBase.GenerateSignature( newUri, oauthConsumerKey, secret, OAuthBase.UrlEncode(oauthToken), oauthTokenSecret, requestType, OAuthBase.UrlEncode(oauthTimeStamp), OAuthBase.UrlEncode(oauthNonce), OAuthBase.SignatureTypes.HMACSHA1, OAuthBase.UrlEncode(oauthVersion), oauthBodyHash, bodyParams, true, false, false); if (OauthSignaturesMatch(oauthSignature, sig, scheme, signatureStage++)) { return(true); } // Try with encoded consumer key since the spec is ambiguous on this point // sig = OAuthBase.GenerateSignature( newUri, OAuthBase.UrlEncode(oauthConsumerKey), secret, OAuthBase.UrlEncode(oauthToken), oauthTokenSecret, requestType, OAuthBase.UrlEncode(oauthTimeStamp), OAuthBase.UrlEncode(oauthNonce), OAuthBase.SignatureTypes.HMACSHA1, OAuthBase.UrlEncode(oauthVersion), OAuthBase.UrlEncode(oauthBodyHash), bodyParams, true, false, false); if (OauthSignaturesMatch(oauthSignature, sig, scheme, signatureStage++)) { return(true); } // If standard did not work, try legacy // sig = OAuthBase.GenerateSignature( newUri, OAuthBase.UrlEncode(oauthConsumerKey), secret, OAuthBase.UrlEncode(oauthToken), oauthTokenSecret, requestType, OAuthBase.UrlEncode(oauthTimeStamp), OAuthBase.UrlEncode(oauthNonce), OAuthBase.SignatureTypes.HMACSHA1, OAuthBase.UrlEncode(oauthVersion), OAuthBase.UrlEncode(oauthBodyHash), bodyParams, false, false, false); if (OauthSignaturesMatch(oauthSignature, sig, scheme, signatureStage++)) { return(true); } // Try legacy with unencoded consumer key // sig = OAuthBase.GenerateSignature( newUri, oauthConsumerKey, secret, OAuthBase.UrlEncode(oauthToken), oauthTokenSecret, requestType, OAuthBase.UrlEncode(oauthTimeStamp), OAuthBase.UrlEncode(oauthNonce), OAuthBase.SignatureTypes.HMACSHA1, OAuthBase.UrlEncode(oauthVersion), OAuthBase.UrlEncode(oauthBodyHash), bodyParams, false, false, false); if (OauthSignaturesMatch(oauthSignature, sig, scheme, signatureStage++)) { return(true); } // Try with request parameters encoded method i.e. OAuth.NET (Magdex) // sig = OAuthBase.GenerateSignature( newUri, oauthConsumerKey, secret, oauthToken, oauthTokenSecret, requestType, oauthTimeStamp, oauthNonce, OAuthBase.SignatureTypes.HMACSHA1, oauthVersion, oauthBodyHash, bodyParams, true, true, true); if (OauthSignaturesMatch(oauthSignature, sig, scheme, signatureStage++)) { return(true); } // Try legacy request_token with callback, allowing oauth_callback parameter // This comes from the MyspaceID SDK signer implementations sig = OAuthBase.GenerateSignature( newUri, oauthConsumerKey, secret, oauthToken, oauthTokenSecret, requestType, oauthTimeStamp, oauthNonce, OAuthBase.SignatureTypes.HMACSHA1, oauthVersion, oauthBodyHash, bodyParams, true, false, false, true); if (OauthSignaturesMatch(oauthSignature, sig, scheme, signatureStage++)) { return(true); } // Try legacy request_token with callback, allowing oauth_callback parameter and encoding consumer key // This comes from the MyspaceID SDK signer implementations sig = OAuthBase.GenerateSignature( newUri, OAuthBase.UrlEncode(oauthConsumerKey), secret, oauthToken, oauthTokenSecret, requestType, oauthTimeStamp, oauthNonce, OAuthBase.SignatureTypes.HMACSHA1, oauthVersion, oauthBodyHash, bodyParams, true, false, false, true); if (OauthSignaturesMatch(oauthSignature, sig, scheme, signatureStage++)) { return(true); } } } return(false); }