Skip to content

Commit 402b1f4

Browse files
authored
Merge pull request #34 from CyberSource/future
Future
2 parents 2fafff1 + 499c074 commit 402b1f4

File tree

16 files changed

+250
-56
lines changed

16 files changed

+250
-56
lines changed

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.0.0")]
35-
[assembly: AssemblyFileVersion("1.0.0")]
34+
[assembly: AssemblyVersion("1.4.0")]
35+
[assembly: AssemblyFileVersion("1.4.0")]

CyberSource/Client/BaseClient.cs

+21-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.ServiceModel;
55
using System.Xml.Serialization;
66
using System.ServiceModel.Channels;
7+
using System.ServiceModel.Security.Tokens;
78

89
namespace CyberSource.Clients
910
{
@@ -15,7 +16,7 @@ public abstract class BaseClient
1516
/// <summary>
1617
/// Version of this client.
1718
/// </summary>
18-
public const string CLIENT_LIBRARY_VERSION = "1.0.1";
19+
public const string CLIENT_LIBRARY_VERSION = "1.4.0";
1920

2021
/// <summary>
2122
/// Proxy object that is initialized during start-up, if needed.
@@ -40,6 +41,9 @@ public abstract class BaseClient
4041
private const string PROXY_PASSWORD = "proxyPassword";
4142
private const string BASIC_AUTH = "Basic";
4243

44+
public const string CYBERSOURCE_PUBLIC_KEY = "CyberSource_SJC_US";
45+
public const string X509_CLAIMTYPE = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/x500distinguishedname";
46+
4347
static BaseClient()
4448
{
4549
SetupProxy();
@@ -211,6 +215,12 @@ int boolVal
211215
= AppSettings.GetIntSetting(
212216
merchantID, Configuration.CONNECTION_LIMIT);
213217

218+
// Encryption enable flag
219+
boolVal
220+
= AppSettings.GetBoolSetting(
221+
merchantID, Configuration.USE_SIGNED_AND_ENCRYPTED);
222+
if (boolVal != -1) config.UseSignedAndEncrypted = (boolVal == 1);
223+
214224
return (config);
215225
}
216226

@@ -303,7 +313,7 @@ protected static void SetConnectionLimit(Configuration config)
303313
/// Returns a custom wcf binding that will create a SOAP request
304314
/// compatible with the Simple Order API Service
305315
/// </summary>
306-
protected static CustomBinding getWCFCustomBinding()
316+
protected static CustomBinding getWCFCustomBinding(Configuration config)
307317
{
308318
//Setup custom binding with HTTPS + Body Signing
309319
CustomBinding currentBinding = new CustomBinding();
@@ -315,6 +325,15 @@ protected static CustomBinding getWCFCustomBinding()
315325
asec.EnableUnsecuredResponse = true;
316326
asec.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
317327

328+
if (config.UseSignedAndEncrypted)
329+
{
330+
asec.LocalClientSettings.IdentityVerifier = new CustomeIdentityVerifier();
331+
asec.RecipientTokenParameters = new System.ServiceModel.Security.Tokens.X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.Once };
332+
asec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt;
333+
asec.EndpointSupportingTokenParameters.SignedEncrypted.Add(new System.ServiceModel.Security.Tokens.X509SecurityTokenParameters());
334+
asec.SetKeyDerivation(false);
335+
}
336+
318337
//Use custom encoder to strip unsigned timestamp in response
319338
CustomTextMessageBindingElement textBindingElement = new CustomTextMessageBindingElement();
320339

CyberSource/Client/Configuration.cs

+8
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class Configuration
2727
internal const string CONNECTION_LIMIT = "connectionLimit";
2828
internal const string SEND_TO_AKAMAI = "sendToAkamai";
2929
internal const string EFFECTIVE_SERVER_URL = "effectiveServerURL";
30+
internal const string USE_SIGNED_AND_ENCRYPTED = "useSignAndEncrypted";
3031

3132
/// <summary>
3233
/// Default log file name.
@@ -68,6 +69,7 @@ public class Configuration
6869
private bool demo = false;
6970
private bool sendToAkamai = true;
7071
private int connectionLimit = -1;
72+
private bool useSignedAndEncrypted = false;
7173

7274
private bool isSendToProductionSet = false;
7375

@@ -406,5 +408,11 @@ private void CheckMerchantID()
406408
"CONFIGURATION OR CODE BUG: merchantID is missing!");
407409
}
408410
}
411+
412+
public bool UseSignedAndEncrypted
413+
{
414+
get { return useSignedAndEncrypted; }
415+
set { useSignedAndEncrypted = value; }
416+
}
409417
}
410418
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IdentityModel.Claims;
4+
using System.IdentityModel.Policy;
5+
using System.Linq;
6+
using System.Security.Cryptography.X509Certificates;
7+
using System.ServiceModel;
8+
using System.ServiceModel.Security;
9+
using System.Text;
10+
11+
namespace CyberSource.Clients
12+
{
13+
class CustomeIdentityVerifier : IdentityVerifier
14+
{
15+
IdentityVerifier defaultVerifier;
16+
17+
public CustomeIdentityVerifier()
18+
{
19+
this.defaultVerifier = CustomeIdentityVerifier.CreateDefault();
20+
}
21+
22+
public override bool CheckAccess(EndpointIdentity identity,
23+
AuthorizationContext authContext)
24+
{
25+
bool returnvalue = false;
26+
foreach (ClaimSet claimset in authContext.ClaimSets)
27+
{
28+
foreach (Claim claim in claimset)
29+
{
30+
if (claim.ClaimType == BaseClient.X509_CLAIMTYPE)
31+
{
32+
X500DistinguishedName name = (X500DistinguishedName)claim.Resource;
33+
if (name.Name.Contains(BaseClient.CYBERSOURCE_PUBLIC_KEY))
34+
{
35+
returnvalue = true;
36+
break;
37+
}
38+
}
39+
}
40+
41+
}
42+
// The following implementation is for demonstration only, and
43+
// does not perform any checks regarding EndpointIdentity.
44+
// Do not use this for production code.
45+
return returnvalue;
46+
}
47+
48+
public override bool TryGetIdentity(EndpointAddress reference,
49+
out EndpointIdentity identity)
50+
{
51+
return this.defaultVerifier.TryGetIdentity(reference, out identity);
52+
}
53+
}
54+
}

CyberSource/Client/CyberSourceClients.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
<ItemGroup>
9898
<Reference Include="System" />
9999
<Reference Include="System.Configuration" />
100+
<Reference Include="System.IdentityModel" />
100101
<Reference Include="System.Runtime.Serialization" />
101102
<Reference Include="System.Security" />
102103
<Reference Include="System.ServiceModel" />
@@ -106,6 +107,7 @@
106107
<Compile Include="AppSettings.cs" />
107108
<Compile Include="BaseClient.cs" />
108109
<Compile Include="Configuration.cs" />
110+
<Compile Include="CustomeIdentityVerifier.cs" />
109111
<Compile Include="CustomTextMessageEncoder.cs" />
110112
<Compile Include="CustomTextMessageEncoderFactory.cs" />
111113
<Compile Include="CustomTextMessageEncodingBindingElement.cs" />

CyberSource/Client/NVPClient.cs

+21-6
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,18 @@ public static Hashtable RunTransaction(
6161
SetConnectionLimit(config);
6262

6363
//Setup custom binding with HTTPS + Body Signing
64-
CustomBinding currentBinding = getWCFCustomBinding();
64+
CustomBinding currentBinding = getWCFCustomBinding(config);
6565

6666
//Setup endpoint Address with dns identity
6767
AddressHeaderCollection headers = new AddressHeaderCollection();
6868
EndpointAddress endpointAddress = new EndpointAddress(new Uri(config.EffectiveServerURL), EndpointIdentity.CreateDnsIdentity(config.EffectivePassword), headers);
6969

7070
//Get instance of service
7171
using (proc = new NVPTransactionProcessorClient(currentBinding, endpointAddress))
72-
{
73-
74-
//Set protection level to sign only
75-
proc.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;
72+
{
73+
74+
//Set protection level to sign
75+
proc.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;
7676

7777
// set the timeout
7878
TimeSpan timeOut = new TimeSpan(0, 0, 0, config.Timeout, 0);
@@ -96,6 +96,21 @@ public static Hashtable RunTransaction(
9696
proc.ClientCredentials.ServiceCertificate.DefaultCertificate = cert1;
9797
break;
9898
}
99+
}
100+
101+
if (config.UseSignedAndEncrypted)
102+
{
103+
foreach (X509Certificate2 cert2 in collection)
104+
{
105+
//Console.WriteLine(cert1.Subject);
106+
if (cert2.Subject.Contains(CYBERSOURCE_PUBLIC_KEY))
107+
{
108+
//Set protection level to sign & encrypt only
109+
proc.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
110+
proc.ClientCredentials.ServiceCertificate.DefaultCertificate = cert2;
111+
break;
112+
}
113+
}
99114
}
100115

101116
if (logger != null)
@@ -207,7 +222,7 @@ private static void SetVersionInformation(Hashtable request)
207222
request["clientLibrary"] = ".NET NVP";
208223
request["clientLibraryVersion"] = CLIENT_LIBRARY_VERSION;
209224
request["clientEnvironment"] = mEnvironmentInfo;
210-
request["clientSecurityLibraryVersion"] =".Net 1.0.0";
225+
request["clientSecurityLibraryVersion"] =".Net 1.4.0";
211226
}
212227
}
213228
}

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.0.0")]
35-
[assembly: AssemblyFileVersion("1.0.0")]
34+
[assembly: AssemblyVersion("1.4.0")]
35+
[assembly: AssemblyFileVersion("1.4.0")]

CyberSource/Client/SoapClient.cs

+21-6
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ public static ReplyMessage RunTransaction(
5858
DetermineEffectiveMerchantID(ref config, requestMessage);
5959
SetVersionInformation(requestMessage);
6060
logger = PrepareLog(config);
61-
SetConnectionLimit(config);
62-
63-
64-
CustomBinding currentBinding = getWCFCustomBinding();
61+
SetConnectionLimit(config);
62+
63+
64+
CustomBinding currentBinding = getWCFCustomBinding(config);
6565

6666

6767
//Setup endpoint Address with dns identity
@@ -71,7 +71,7 @@ public static ReplyMessage RunTransaction(
7171
//Get instance of service
7272
using( proc = new TransactionProcessorClient(currentBinding, endpointAddress)){
7373

74-
//Set protection level to sign only
74+
//Set protection level to sign & encrypt only
7575
proc.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;
7676

7777
// set the timeout
@@ -96,6 +96,21 @@ public static ReplyMessage RunTransaction(
9696
proc.ClientCredentials.ServiceCertificate.DefaultCertificate = cert1;
9797
break;
9898
}
99+
}
100+
101+
if (config.UseSignedAndEncrypted)
102+
{
103+
foreach (X509Certificate2 cert2 in collection)
104+
{
105+
//Console.WriteLine(cert1.Subject);
106+
if (cert2.Subject.Contains(CYBERSOURCE_PUBLIC_KEY))
107+
{
108+
//Set protection level to sign & encrypt only
109+
proc.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
110+
proc.ClientCredentials.ServiceCertificate.DefaultCertificate = cert2;
111+
break;
112+
}
113+
}
99114
}
100115

101116
// send request now
@@ -200,7 +215,7 @@ private static void SetVersionInformation(
200215
requestMessage.clientLibrary = ".NET Soap";
201216
requestMessage.clientLibraryVersion = CLIENT_LIBRARY_VERSION;
202217
requestMessage.clientEnvironment = mEnvironmentInfo;
203-
requestMessage.clientSecurityLibraryVersion =".Net 1.0.0";
218+
requestMessage.clientSecurityLibraryVersion =".Net 1.4.0";
204219
}
205220
}
206221
}

0 commit comments

Comments
 (0)