@@ -25,6 +25,7 @@ public class SecurityUtils
25
25
/// Constants for formatting the request textual representation for signing.
26
26
/// </summary>
27
27
private const string NEWLINE = "\n " ;
28
+ private const string WINDOWS_NEWLINE = "\r \n " ;
28
29
private const string FORMAT_METHOD_AND_ENDPOINT_STRING = "{0} /v1/{1}" ;
29
30
private const string HEADER_NAME_PREFIX_X_BUNQ = "X-Bunq-" ;
30
31
private const string DELIMITER_HEADER_VALUE = "," ;
@@ -38,12 +39,17 @@ public class SecurityUtils
38
39
/// <summary>
39
40
/// Constants for formatting RSA keys.
40
41
/// </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 ;
47
53
48
54
/// <summary>
49
55
/// Size of the encryption key.
@@ -209,8 +215,10 @@ public static string GetPrivateKeyFormattedString(RSA keyPair)
209
215
public static RSA CreateKeyPairFromPrivateKeyFormattedString ( string privateKeyString )
210
216
{
211
217
var privateKeyStringTrimmed = privateKeyString
218
+ . Replace ( WINDOWS_NEWLINE , NEWLINE )
212
219
. Replace ( PRIVATE_KEY_START , string . Empty )
213
- . Replace ( PRIVATE_KEY_END , string . Empty ) ;
220
+ . Replace ( PRIVATE_KEY_END , string . Empty )
221
+ . Trim ( ) ;
214
222
215
223
return RsaKeyUtils . DecodePrivateKeyInfo ( Convert . FromBase64String ( privateKeyStringTrimmed ) ) ;
216
224
}
@@ -221,8 +229,10 @@ public static RSA CreateKeyPairFromPrivateKeyFormattedString(string privateKeySt
221
229
public static RSA CreateKeyPairFromRsaPrivateKeyFormattedString ( string privateKeyString )
222
230
{
223
231
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 ( ) ;
226
236
227
237
return RsaKeyUtils . DecodeRsaPrivateKey ( Convert . FromBase64String ( privateKeyStringTrimmed ) ) ;
228
238
}
@@ -233,8 +243,10 @@ public static RSA CreateKeyPairFromRsaPrivateKeyFormattedString(string privateKe
233
243
public static RSA CreatePublicKeyFromPublicKeyFormattedString ( string publicKeyString )
234
244
{
235
245
var publicKeyStringTrimmed = publicKeyString
246
+ . Replace ( WINDOWS_NEWLINE , NEWLINE )
236
247
. Replace ( PUBLIC_KEY_START , string . Empty )
237
- . Replace ( PUBLIC_KEY_END , string . Empty ) ;
248
+ . Replace ( PUBLIC_KEY_END , string . Empty )
249
+ . Trim ( ) ;
238
250
239
251
return RsaKeyUtils . DecodePublicKey ( Convert . FromBase64String ( publicKeyStringTrimmed ) ) ;
240
252
}
@@ -355,27 +367,32 @@ private static string GenerateResponseHeadersSortedString(HttpResponseMessage re
355
367
) ;
356
368
}
357
369
370
+ /// <summary>
371
+ /// Creates a PEM-formatted certificate string from a given X509Certificate object
372
+ /// string.
373
+ /// </summary>
358
374
public static string ExportCertificateToPEM ( X509Certificate cert )
359
375
{
360
- StringBuilder builder = new StringBuilder ( ) ;
376
+ var certificateBytes = cert . Export ( X509ContentType . Cert ) ;
361
377
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 ) ) ) ;
368
379
}
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>
370
386
private static string WrapBase64 ( string base64 )
371
387
{
372
- StringBuilder builder = new StringBuilder ( ) ;
388
+ var builder = new StringBuilder ( ) ;
373
389
for ( var ctr = 0 ; ctr <= base64 . Length / 64 ; ctr ++ )
374
390
{
375
- builder . AppendLine ( base64 . Substring ( ctr * 64 ,
391
+ builder . Append ( base64 . Substring ( ctr * 64 ,
376
392
ctr * 64 + 64 <= base64 . Length
377
393
? 64
378
- : base64 . Length - ctr * 64 ) ) ;
394
+ : base64 . Length - ctr * 64 ) )
395
+ . Append ( NEWLINE ) ;
379
396
}
380
397
381
398
return builder . ToString ( ) . Trim ( ) ;
@@ -387,7 +404,7 @@ public static string ExportCertificateCollectionToPEM(X509CertificateCollection
387
404
388
405
foreach ( var chainElement in certChain )
389
406
{
390
- builder . AppendLine ( ExportCertificateToPEM ( chainElement ) ) ;
407
+ builder . Append ( ExportCertificateToPEM ( chainElement ) ) . Append ( NEWLINE ) ;
391
408
}
392
409
393
410
return builder . ToString ( ) ;
0 commit comments