Skip to content

Commit 721f0e6

Browse files
authored
Merge pull request #126 from bunq/bunq/sdk_csharp#124_fix_psd2_signing_on_windows
Fix Windows issues. (#124)
2 parents b03e12d + 2e15140 commit 721f0e6

File tree

2 files changed

+44
-27
lines changed

2 files changed

+44
-27
lines changed

BunqSdk/Context/SessionContext.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -90,27 +90,27 @@ private static double GetSessionTimeout(SessionServer sessionServer)
9090
{
9191
if (sessionServer.UserApiKey != null)
9292
{
93-
return GetSesisonTimeOutForUser(sessionServer.UserApiKey.RequestedByUser.GetReferencedObject());
93+
return GetSessionTimeOutForUser(sessionServer.UserApiKey.RequestedByUser.GetReferencedObject());
9494
}
9595
else if (sessionServer.UserCompany != null)
9696
{
97-
return GetSesisonTimeOutForUser(sessionServer.UserCompany);
97+
return GetSessionTimeOutForUser(sessionServer.UserCompany);
9898
}
9999
else if (sessionServer.UserPerson != null)
100100
{
101-
return GetSesisonTimeOutForUser(sessionServer.UserPerson);
101+
return GetSessionTimeOutForUser(sessionServer.UserPerson);
102102
}
103103
else if (sessionServer.UserPaymentServiceProvider != null)
104104
{
105-
return GetSesisonTimeOutForUser(sessionServer.UserPaymentServiceProvider);
105+
return GetSessionTimeOutForUser(sessionServer.UserPaymentServiceProvider);
106106
}
107107
else
108108
{
109109
throw new BunqException(ErrorCouldNotDetermineSessionTimeout);
110110
}
111111
}
112112

113-
private static double GetSesisonTimeOutForUser(BunqModel user)
113+
private static double GetSessionTimeOutForUser(BunqModel user)
114114
{
115115
int? sessionTimeout;
116116

BunqSdk/Security/SecurityUtils.cs

+39-22
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class SecurityUtils
2525
/// Constants for formatting the request textual representation for signing.
2626
/// </summary>
2727
private const string NEWLINE = "\n";
28+
private const string WINDOWS_NEWLINE = "\r\n";
2829
private const string FORMAT_METHOD_AND_ENDPOINT_STRING = "{0} /v1/{1}";
2930
private const string HEADER_NAME_PREFIX_X_BUNQ = "X-Bunq-";
3031
private const string DELIMITER_HEADER_VALUE = ",";
@@ -38,12 +39,17 @@ public class SecurityUtils
3839
/// <summary>
3940
/// Constants for formatting RSA keys.
4041
/// </summary>
41-
private const string PUBLIC_KEY_START = "-----BEGIN PUBLIC KEY-----\n";
42-
private const string PUBLIC_KEY_END = "\n-----END PUBLIC KEY-----\n";
43-
private const string FORMAT_PUBLIC_KEY = PUBLIC_KEY_START + "{0}" + PUBLIC_KEY_END;
44-
private const string PRIVATE_KEY_START = "-----BEGIN PRIVATE KEY-----\n";
45-
private const string PRIVATE_KEY_END = "\n-----END PRIVATE KEY-----\n";
46-
private const string FORMAT_PRIVATE_KEY = PRIVATE_KEY_START + "{0}" + PRIVATE_KEY_END;
42+
private const string PUBLIC_KEY_START = "-----BEGIN PUBLIC KEY-----" + NEWLINE;
43+
private const string PUBLIC_KEY_END = NEWLINE + "-----END PUBLIC KEY-----";
44+
private const string FORMAT_PUBLIC_KEY = PUBLIC_KEY_START + "{0}" + PUBLIC_KEY_END + NEWLINE;
45+
private const string PRIVATE_KEY_START = "-----BEGIN PRIVATE KEY-----" + NEWLINE;
46+
private const string PRIVATE_KEY_END = NEWLINE + "-----END PRIVATE KEY-----";
47+
private const string FORMAT_PRIVATE_KEY = PRIVATE_KEY_START + "{0}" + PRIVATE_KEY_END + NEWLINE;
48+
private const string RSA_PRIVATE_KEY_START = "-----BEGIN RSA PRIVATE KEY-----" + NEWLINE;
49+
private const string RSA_PRIVATE_KEY_END = NEWLINE + "-----END RSA PRIVATE KEY-----";
50+
private const string CERTIFICATE_START = "-----BEGIN CERTIFICATE-----" + NEWLINE;
51+
private const string CERTIFICATE_END = NEWLINE + "-----END CERTIFICATE-----";
52+
private const string FORMAT_CERTIFICATE = CERTIFICATE_START + "{0}" + CERTIFICATE_END + NEWLINE;
4753

4854
/// <summary>
4955
/// Size of the encryption key.
@@ -209,8 +215,10 @@ public static string GetPrivateKeyFormattedString(RSA keyPair)
209215
public static RSA CreateKeyPairFromPrivateKeyFormattedString(string privateKeyString)
210216
{
211217
var privateKeyStringTrimmed = privateKeyString
218+
.Replace(WINDOWS_NEWLINE, NEWLINE)
212219
.Replace(PRIVATE_KEY_START, string.Empty)
213-
.Replace(PRIVATE_KEY_END, string.Empty);
220+
.Replace(PRIVATE_KEY_END, string.Empty)
221+
.Trim();
214222

215223
return RsaKeyUtils.DecodePrivateKeyInfo(Convert.FromBase64String(privateKeyStringTrimmed));
216224
}
@@ -221,8 +229,10 @@ public static RSA CreateKeyPairFromPrivateKeyFormattedString(string privateKeySt
221229
public static RSA CreateKeyPairFromRsaPrivateKeyFormattedString(string privateKeyString)
222230
{
223231
var privateKeyStringTrimmed = privateKeyString
224-
.Replace("-----BEGIN RSA PRIVATE KEY-----\n", "")
225-
.Replace("\n-----END RSA PRIVATE KEY-----\n", "");
232+
.Replace(WINDOWS_NEWLINE, NEWLINE)
233+
.Replace(RSA_PRIVATE_KEY_START, String.Empty)
234+
.Replace(RSA_PRIVATE_KEY_END, String.Empty)
235+
.Trim();
226236

227237
return RsaKeyUtils.DecodeRsaPrivateKey(Convert.FromBase64String(privateKeyStringTrimmed));
228238
}
@@ -233,8 +243,10 @@ public static RSA CreateKeyPairFromRsaPrivateKeyFormattedString(string privateKe
233243
public static RSA CreatePublicKeyFromPublicKeyFormattedString(string publicKeyString)
234244
{
235245
var publicKeyStringTrimmed = publicKeyString
246+
.Replace(WINDOWS_NEWLINE, NEWLINE)
236247
.Replace(PUBLIC_KEY_START, string.Empty)
237-
.Replace(PUBLIC_KEY_END, string.Empty);
248+
.Replace(PUBLIC_KEY_END, string.Empty)
249+
.Trim();
238250

239251
return RsaKeyUtils.DecodePublicKey(Convert.FromBase64String(publicKeyStringTrimmed));
240252
}
@@ -355,27 +367,32 @@ private static string GenerateResponseHeadersSortedString(HttpResponseMessage re
355367
);
356368
}
357369

370+
/// <summary>
371+
/// Creates a PEM-formatted certificate string from a given X509Certificate object
372+
/// string.
373+
/// </summary>
358374
public static string ExportCertificateToPEM(X509Certificate cert)
359375
{
360-
StringBuilder builder = new StringBuilder();
376+
var certificateBytes = cert.Export(X509ContentType.Cert);
361377

362-
builder.AppendLine("-----BEGIN CERTIFICATE-----");
363-
var base64 = Convert.ToBase64String(cert.Export(X509ContentType.Cert));
364-
builder.AppendLine(WrapBase64(base64));
365-
builder.AppendLine("-----END CERTIFICATE-----");
366-
367-
return builder.ToString();
378+
return string.Format(FORMAT_CERTIFICATE, WrapBase64(Convert.ToBase64String(certificateBytes)));
368379
}
369-
380+
381+
/// <summary>
382+
/// Wraps a base64 string to 64-character wide lines according to typical certificate/key export rules.
383+
/// </summary>
384+
/// <param name="base64">base64 string without line breaks</param>
385+
/// <returns>base64-string formatted with line breaks</returns>
370386
private static string WrapBase64(string base64)
371387
{
372-
StringBuilder builder = new StringBuilder();
388+
var builder = new StringBuilder();
373389
for (var ctr = 0; ctr <= base64.Length / 64; ctr++)
374390
{
375-
builder.AppendLine(base64.Substring(ctr * 64,
391+
builder.Append(base64.Substring(ctr * 64,
376392
ctr * 64 + 64 <= base64.Length
377393
? 64
378-
: base64.Length - ctr * 64));
394+
: base64.Length - ctr * 64))
395+
.Append(NEWLINE);
379396
}
380397

381398
return builder.ToString().Trim();
@@ -387,7 +404,7 @@ public static string ExportCertificateCollectionToPEM(X509CertificateCollection
387404

388405
foreach (var chainElement in certChain)
389406
{
390-
builder.AppendLine(ExportCertificateToPEM(chainElement));
407+
builder.Append(ExportCertificateToPEM(chainElement)).Append(NEWLINE);
391408
}
392409

393410
return builder.ToString();

0 commit comments

Comments
 (0)