Secure OneDrive auth per PCKE recommendations

This commit is contained in:
SupSuper 2018-04-13 17:07:27 +01:00
parent 5f77d55523
commit 080bce2126
5 changed files with 72 additions and 0 deletions

View file

@ -85,6 +85,11 @@ public string GetAuthorizationURL()
args.Add("scope", "offline_access files.readwrite");
args.Add("response_type", "code");
args.Add("redirect_uri", Links.URL_CALLBACK);
if (AuthInfo.Proof != null)
{
args.Add("code_challenge", AuthInfo.Proof.CodeChallenge);
args.Add("code_challenge_method", AuthInfo.Proof.ChallengeMethod);
}
return URLHelpers.CreateQuery(AuthorizationEndpoint, args);
}
@ -97,6 +102,10 @@ public bool GetAccessToken(string code)
args.Add("client_secret", AuthInfo.Client_Secret);
args.Add("code", code);
args.Add("grant_type", "authorization_code");
if (AuthInfo.Proof != null)
{
args.Add("code_verifier", AuthInfo.Proof.CodeVerifier);
}
string response = SendRequestURLEncoded(HttpMethod.POST, TokenEndpoint, args);

View file

@ -711,6 +711,7 @@ public void OneDriveAuthOpen()
try
{
OAuth2Info oauth = new OAuth2Info(APIKeys.OneDriveClientID, APIKeys.OneDriveClientSecret);
oauth.Proof = new OAuth2ProofKey(OAuth2ChallengeMethod.SHA256);
string url = new OneDrive(oauth).GetAuthorizationURL();
if (!string.IsNullOrEmpty(url))

View file

@ -30,6 +30,7 @@ public class OAuth2Info
public string Client_ID { get; set; }
public string Client_Secret { get; set; }
public OAuth2Token Token { get; set; }
public OAuth2ProofKey Proof { get; set; }
public OAuth2Info(string client_id, string client_secret)
{

View file

@ -0,0 +1,60 @@
using System;
using System.Security.Cryptography;
using System.Text;
namespace ShareX.UploadersLib
{
public enum OAuth2ChallengeMethod
{
Plain, SHA256
}
public class OAuth2ProofKey
{
public string CodeVerifier { get; private set; }
public string CodeChallenge { get; private set; }
private OAuth2ChallengeMethod Method;
public string ChallengeMethod
{
get
{
switch (Method)
{
case OAuth2ChallengeMethod.Plain: return "plain";
case OAuth2ChallengeMethod.SHA256: return "S256";
}
return "";
}
}
public OAuth2ProofKey(OAuth2ChallengeMethod method)
{
Method = method;
var buffer = new byte[32];
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(buffer);
CodeVerifier = CleanBase64(buffer);
CodeChallenge = CodeVerifier;
if (Method == OAuth2ChallengeMethod.SHA256)
{
var sha = new SHA256Managed();
sha.ComputeHash(Encoding.UTF8.GetBytes(CodeVerifier));
CodeChallenge = CleanBase64(sha.Hash);
}
}
private string CleanBase64(byte[] buffer)
{
var sb = new StringBuilder(Convert.ToBase64String(buffer));
sb.Replace('+', '-');
sb.Replace('/', '_');
sb.Replace("=", "");
return sb.ToString();
}
}
}

View file

@ -243,6 +243,7 @@
<Compile Include="Helpers\EscapeHelper.cs" />
<Compile Include="Helpers\GoogleOAuth2.cs" />
<Compile Include="Helpers\OAuth\IOAuthBase.cs" />
<Compile Include="Helpers\OAuth\OAuth2ProofKey.cs" />
<Compile Include="Helpers\SSLBypassHelper.cs" />
<Compile Include="BaseServices\URLSharingService.cs" />
<Compile Include="OtherServices\OCRSpace.cs" />