From 6c97a238f684ad9138ca4727b8d8464edbf9819f Mon Sep 17 00:00:00 2001 From: Kevin Hellemun Date: Thu, 21 Dec 2017 15:26:22 +0100 Subject: [PATCH 1/3] Insure that headers are correclty cased before signature verification. (bunq/sdk_csharp#49) --- BunqSdk/Security/SecurityUtils.cs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/BunqSdk/Security/SecurityUtils.cs b/BunqSdk/Security/SecurityUtils.cs index 235b280..ac74cc1 100644 --- a/BunqSdk/Security/SecurityUtils.cs +++ b/BunqSdk/Security/SecurityUtils.cs @@ -6,6 +6,7 @@ using System.Security; using System.Security.Cryptography; using System.Text; +using System.Text.RegularExpressions; using Bunq.Sdk.Context; using Bunq.Sdk.Exception; using Bunq.Sdk.Http; @@ -77,6 +78,11 @@ public class SecurityUtils /// Number of the very first index in an array or a string. /// private const int INDEX_FIRST = 0; + + /// + /// Regex constants. + /// + private const string REGEX_FOR_LOWERCASE_HEADERS = "(-[a-z])"; /// /// Generates a base64-representation of RSA/SHA256/PKCS1 signature for a given RequestMessage. @@ -127,6 +133,20 @@ private static string GenerateRequestHeadersSortedString(HttpRequestMessage requ ); } + private static string GetHeaderNameCorrectyCased(string headerName) + { + headerName = headerName.ToLower(); + headerName = headerName.First().ToString().ToUpper() + headerName.Substring(1); + var matches = Regex.Matches(headerName, REGEX_FOR_LOWERCASE_HEADERS); + + return matches.Cast().Aggregate( + headerName, + (current, match) => current.Replace( + match.Groups[INDEX_FIRST].Value, match.Groups[INDEX_FIRST].Value.ToUpper() + ) + ); + } + private static string GenerateHeadersSortedString( IEnumerable>> headers) { @@ -307,8 +327,8 @@ private static string GenerateResponseHeadersSortedString(HttpResponseMessage re { return GenerateHeadersSortedString( responseMessage.Headers.Where(x => - x.Key.StartsWith(HEADER_NAME_PREFIX_X_BUNQ) && - !x.Key.Equals(HEADER_SERVER_SIGNATURE) + GetHeaderNameCorrectyCased(x.Key).StartsWith(HEADER_NAME_PREFIX_X_BUNQ) && + !GetHeaderNameCorrectyCased(x.Key).Equals(HEADER_SERVER_SIGNATURE) ) ); } From f7155deb4a874dba22ff8a43fa9cc2caa70f85d0 Mon Sep 17 00:00:00 2001 From: Kevin Hellemun Date: Thu, 21 Dec 2017 16:20:08 +0100 Subject: [PATCH 2/3] Adde constant for magic value. (bunq/sdk_csharp#49) --- BunqSdk/Security/SecurityUtils.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/BunqSdk/Security/SecurityUtils.cs b/BunqSdk/Security/SecurityUtils.cs index ac74cc1..07c9945 100644 --- a/BunqSdk/Security/SecurityUtils.cs +++ b/BunqSdk/Security/SecurityUtils.cs @@ -78,6 +78,11 @@ public class SecurityUtils /// Number of the very first index in an array or a string. /// private const int INDEX_FIRST = 0; + + /// + /// The index after the firts character in a string. + /// + private const int INDEX_LAST_FIRST_CHAR = 1; /// /// Regex constants. @@ -136,7 +141,7 @@ private static string GenerateRequestHeadersSortedString(HttpRequestMessage requ private static string GetHeaderNameCorrectyCased(string headerName) { headerName = headerName.ToLower(); - headerName = headerName.First().ToString().ToUpper() + headerName.Substring(1); + headerName = headerName.First().ToString().ToUpper() + headerName.Substring(INDEX_LAST_FIRST_CHAR); var matches = Regex.Matches(headerName, REGEX_FOR_LOWERCASE_HEADERS); return matches.Cast().Aggregate( From 2944f3f7786dd774f86b857ce72923d6b86b1785 Mon Sep 17 00:00:00 2001 From: Kevin Hellemun Date: Thu, 21 Dec 2017 16:53:30 +0100 Subject: [PATCH 3/3] Fixed typo in GetHeaderNameCorrectlyCased. (bunq/sdk_csharp#49) --- BunqSdk/Security/SecurityUtils.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BunqSdk/Security/SecurityUtils.cs b/BunqSdk/Security/SecurityUtils.cs index 07c9945..c08004e 100644 --- a/BunqSdk/Security/SecurityUtils.cs +++ b/BunqSdk/Security/SecurityUtils.cs @@ -138,7 +138,7 @@ private static string GenerateRequestHeadersSortedString(HttpRequestMessage requ ); } - private static string GetHeaderNameCorrectyCased(string headerName) + private static string GetHeaderNameCorrectlyCased(string headerName) { headerName = headerName.ToLower(); headerName = headerName.First().ToString().ToUpper() + headerName.Substring(INDEX_LAST_FIRST_CHAR); @@ -332,8 +332,8 @@ private static string GenerateResponseHeadersSortedString(HttpResponseMessage re { return GenerateHeadersSortedString( responseMessage.Headers.Where(x => - GetHeaderNameCorrectyCased(x.Key).StartsWith(HEADER_NAME_PREFIX_X_BUNQ) && - !GetHeaderNameCorrectyCased(x.Key).Equals(HEADER_SERVER_SIGNATURE) + GetHeaderNameCorrectlyCased(x.Key).StartsWith(HEADER_NAME_PREFIX_X_BUNQ) && + !GetHeaderNameCorrectlyCased(x.Key).Equals(HEADER_SERVER_SIGNATURE) ) ); }