Skip to content

Commit 94c782a

Browse files
authored
Merge pull request #70 from CyberSource/security-fixes
Security fixes
2 parents 25a1952 + d503fd1 commit 94c782a

File tree

10 files changed

+102
-30
lines changed

10 files changed

+102
-30
lines changed

CyberSource.nuspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package >
33
<metadata>
44
<id>CyberSource</id>
5-
<version>1.4.6</version>
5+
<version>1.4.7</version>
66
<title>CyberSource Corporation</title>
77
<authors>CyberSource Corporation</authors>
88
<owners>CyberSource Corporation</owners>

CyberSource/Base/Properties/AssemblyInfo.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@
3131
//
3232
// You can specify all the values or you can default the Revision and Build Numbers
3333
// by using the '*' as shown below:
34-
[assembly: AssemblyVersion("1.4.6")]
35-
[assembly: AssemblyFileVersion("1.4.6")]
34+
[assembly: AssemblyVersion("1.4.7")]
35+
[assembly: AssemblyFileVersion("1.4.7")]

CyberSource/Client/BaseClient.cs

+29-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
using System.ServiceModel.Channels;
88
using System.ServiceModel.Security.Tokens;
99
using System.Security.Cryptography.X509Certificates;
10-
using System.Collections.Concurrent;
10+
using System.Collections.Concurrent;
11+
using System.Security;
1112

1213
namespace CyberSource.Clients
1314
{
@@ -70,15 +71,22 @@ string proxyUser
7071
= AppSettings.GetSetting(null, PROXY_USER);
7172
if (proxyUser != null)
7273
{
73-
string proxyPassword
74-
= AppSettings.GetSetting(null, PROXY_PASSWORD);
74+
SecureString proxyPassword = new SecureString();
75+
76+
foreach (char c in AppSettings.GetSetting(null, PROXY_PASSWORD))
77+
{
78+
proxyPassword.AppendChar(c);
79+
}
80+
81+
proxyPassword.MakeReadOnly();
7582

7683
NetworkCredential credential
7784
= new NetworkCredential(proxyUser, proxyPassword);
7885

7986
CredentialCache cache = new CredentialCache();
8087
cache.Add(new Uri(proxyURL), BASIC_AUTH, credential);
8188
mProxy.Credentials = cache;
89+
proxyPassword.Dispose();
8290
}
8391
}
8492
}
@@ -201,8 +209,8 @@ int boolVal
201209
merchantID, Configuration.KEY_ALIAS);
202210

203211
config.Password
204-
= AppSettings.GetSetting(
205-
merchantID, Configuration.PASSWORD);
212+
= convertToSecureString(AppSettings.GetSetting(
213+
merchantID, Configuration.PASSWORD));
206214

207215
config.LogFilename
208216
= AppSettings.GetSetting(
@@ -422,6 +430,22 @@ public static bool IsMerchantCertExpired(Logger logger, string merchantId, DateT
422430

423431
}
424432
return false;
433+
}
434+
435+
private static SecureString convertToSecureString(string originalString)
436+
{
437+
if (originalString == null)
438+
{
439+
return null;
440+
}
441+
442+
var secureString = new SecureString();
443+
444+
foreach (char c in originalString)
445+
secureString.AppendChar(c);
446+
447+
secureString.MakeReadOnly();
448+
return secureString;
425449
}
426450
}
427451
}

CyberSource/Client/Configuration.cs

+21-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Security;
23

34
namespace CyberSource.Clients
45
{
@@ -65,7 +66,7 @@ public class Configuration
6566
private string serverURL = null;
6667
private string keyFilename = null;
6768
private string keyAlias = null;
68-
private string password = null;
69+
private SecureString password = null;
6970
private string logFilename = null;
7071
private int logMaximumSize = -1;
7172
private int timeout = -1;
@@ -195,7 +196,7 @@ public string KeyAlias
195196
/// This is optional. When not set, the value of MerchantID is
196197
/// used.
197198
/// </summary>
198-
public string Password
199+
public SecureString Password
199200
{
200201
get { return password; }
201202
set { password = value; }
@@ -409,14 +410,30 @@ internal string EffectiveKeyFilename
409410
/// Returns the password that will take effect given
410411
/// the current state of this Configuration object.
411412
/// </summary>
412-
internal string EffectivePassword
413+
internal SecureString EffectivePassword
413414
{
414415
get
415416
{
416-
return( password != null ? password : merchantID);
417+
return( password != null ? password : convertToSecureString(merchantID));
417418
}
418419
}
419420

421+
private SecureString convertToSecureString(string originalString)
422+
{
423+
if (originalString == null)
424+
{
425+
return null;
426+
}
427+
428+
var secureString = new SecureString();
429+
430+
foreach (char c in originalString)
431+
secureString.AppendChar(c);
432+
433+
secureString.MakeReadOnly();
434+
return secureString;
435+
}
436+
420437
/// <summary>
421438
/// Returns the merchantID. Throws an exception when it is null.
422439
/// </summary>

CyberSource/Client/NVPClient.cs

+10-6
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,12 @@ public static Hashtable RunTransaction(
8686
if (logger != null)
8787
{
8888
logger.LogInfo("Loading certificate for " + config.KeyAlias);
89-
}
90-
X509Certificate2Collection collection = new X509Certificate2Collection();
91-
collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
89+
}
90+
91+
X509Certificate2 userCertificate = new X509Certificate2(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
92+
93+
X509Certificate2Collection collection = new X509Certificate2Collection();
94+
collection.Add(userCertificate);
9295

9396
X509Certificate2 newMerchantCert = null;
9497
X509Certificate2 newCybsCert = null;
@@ -121,9 +124,10 @@ public static Hashtable RunTransaction(
121124
}
122125
else
123126
{
124-
// Changes for SHA2 certificates support
125-
X509Certificate2Collection collection = new X509Certificate2Collection();
126-
collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
127+
X509Certificate2 userCertificate = new X509Certificate2(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
128+
129+
X509Certificate2Collection collection = new X509Certificate2Collection();
130+
collection.Add(userCertificate);
127131

128132
foreach (X509Certificate2 cert1 in collection)
129133
{

CyberSource/Client/Properties/AssemblyInfo.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@
3131
//
3232
// You can specify all the values or you can default the Revision and Build Numbers
3333
// by using the '*' as shown below:
34-
[assembly: AssemblyVersion("1.4.6")]
35-
[assembly: AssemblyFileVersion("1.4.6")]
34+
[assembly: AssemblyVersion("1.4.7")]
35+
[assembly: AssemblyFileVersion("1.4.7")]

CyberSource/Client/Service References/SoapServiceReference/Reference.cs

+23-3
Original file line numberDiff line numberDiff line change
@@ -47985,7 +47985,7 @@ public partial class PayerAuthEnrollService : object, System.ComponentModel.INot
4798547985

4798647986
private string loginIDField;
4798747987

47988-
private string passwordField;
47988+
private System.Security.SecureString passwordField;
4798947989

4799047990
private string merchantIDField;
4799147991

@@ -48227,10 +48227,11 @@ public string loginID {
4822748227
[System.Xml.Serialization.XmlElementAttribute(Order=9)]
4822848228
public string password {
4822948229
get {
48230-
return this.passwordField;
48230+
return ConvertToUnsecureString(this.passwordField);
4823148231
}
4823248232
set {
48233-
this.passwordField = value;
48233+
this.passwordField = new System.Net.NetworkCredential(string.Empty, value).SecurePassword;
48234+
this.passwordField.MakeReadOnly();
4823448235
this.RaisePropertyChanged("password");
4823548236
}
4823648237
}
@@ -49011,6 +49012,25 @@ protected void RaisePropertyChanged(string propertyName) {
4901149012
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
4901249013
}
4901349014
}
49015+
49016+
public static string ConvertToUnsecureString(System.Security.SecureString secureString)
49017+
{
49018+
if (secureString == null)
49019+
{
49020+
return string.Empty;
49021+
}
49022+
49023+
System.IntPtr unmanagedString = System.IntPtr.Zero;
49024+
try
49025+
{
49026+
unmanagedString = System.Runtime.InteropServices.Marshal.SecureStringToGlobalAllocUnicode(secureString);
49027+
return System.Runtime.InteropServices.Marshal.PtrToStringUni(unmanagedString);
49028+
}
49029+
finally
49030+
{
49031+
System.Runtime.InteropServices.Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
49032+
}
49033+
}
4901449034
}
4901549035

4901649036
/// <remarks/>

CyberSource/Client/SoapClient.cs

+7-3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public static ReplyMessage RunTransaction(
8181
X509Certificate2 merchantCert = null;
8282
X509Certificate2 cybsCert = null;
8383
DateTime dateFile = File.GetLastWriteTime(keyFilePath);
84+
8485
if (config.CertificateCacheEnabled)
8586
{
8687
if (!merchantIdentities.ContainsKey(config.KeyAlias) || IsMerchantCertExpired(logger, config.KeyAlias, dateFile, merchantIdentities))
@@ -90,8 +91,10 @@ public static ReplyMessage RunTransaction(
9091
logger.LogInfo("Loading certificate for " + config.KeyAlias);
9192
}
9293

94+
X509Certificate2 userCertificate = new X509Certificate2(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
95+
9396
X509Certificate2Collection collection = new X509Certificate2Collection();
94-
collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
97+
collection.Add(userCertificate);
9598

9699
X509Certificate2 newMerchantCert = null;
97100
X509Certificate2 newCybsCert = null;
@@ -124,9 +127,10 @@ public static ReplyMessage RunTransaction(
124127
}
125128
else
126129
{
127-
// Changes for SHA2 certificates support
130+
X509Certificate2 userCertificate = new X509Certificate2(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
131+
128132
X509Certificate2Collection collection = new X509Certificate2Collection();
129-
collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
133+
collection.Add(userCertificate);
130134

131135
foreach (X509Certificate2 cert1 in collection)
132136
{

CyberSource/Client/XmlClient.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,10 @@ public static XmlDocument RunTransaction(
106106
logger.LogInfo("Loading certificate for "+ config.KeyAlias);
107107
}
108108

109+
X509Certificate2 userCertificate = new X509Certificate2(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
110+
109111
X509Certificate2Collection collection = new X509Certificate2Collection();
110-
collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
112+
collection.Add(userCertificate);
111113

112114
X509Certificate2 newMerchantCert = null;
113115
X509Certificate2 newCybsCert = null;
@@ -140,8 +142,11 @@ public static XmlDocument RunTransaction(
140142
}
141143
else
142144
{
145+
X509Certificate2 userCertificate = new X509Certificate2(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
146+
143147
X509Certificate2Collection collection = new X509Certificate2Collection();
144-
collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
148+
collection.Add(userCertificate);
149+
145150
foreach (X509Certificate2 cert1 in collection)
146151
{
147152
if (cert1.Subject.Contains(config.KeyAlias))

CyberSourceSamples/src/soap/SoapSample.cs

-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using CyberSource.Clients;
66
using CyberSource.Clients.SoapServiceReference;
77
using System.Security.Cryptography;
8-
//using SoapSampleTransactions;
98

109

1110
namespace CyberSource.Samples
@@ -845,7 +844,6 @@ public RequestMessage saleRequest()
845844
// you would set a merchantID in each request.
846845

847846
// this sample requests auth and capture
848-
849847
// Credit Card Authorization
850848
request.ccAuthService = new CCAuthService();
851849
request.ccAuthService.run = "true";

0 commit comments

Comments
 (0)