diff --git a/CyberSource/Client/BaseClient.cs b/CyberSource/Client/BaseClient.cs
index 6f3b1aa..d1cbcdc 100644
--- a/CyberSource/Client/BaseClient.cs
+++ b/CyberSource/Client/BaseClient.cs
@@ -1,6 +1,7 @@
using CyberSource.Base;
using System;
using System.Net;
+using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.Xml.Serialization;
using System.ServiceModel.Channels;
@@ -359,5 +360,38 @@ protected static CustomBinding getWCFCustomBinding(Configuration config)
currentBinding.Elements.Add(httpsTransport);
return currentBinding;
}
+
+ ///
+ /// Creates a new instance of X509Certificate2
+ ///
+ ///
+ /// Configuration object containing the key content or file path
+ ///
+ /// New instance of X509Certificate2
+ protected static X509Certificate2 GetCertificate(Configuration config)
+ {
+ var flags = X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet;
+ return config.Key != null
+ ? new X509Certificate2(config.Key, config.EffectivePassword, flags)
+ : new X509Certificate2(config.EffectiveKeyFilePath, config.EffectivePassword, flags);
+ }
+
+ ///
+ /// Creates a certificate collection with an imported certificate
+ ///
+ ///
+ /// Configuration object containing the key content or file path
+ ///
+ /// New instance of X509Certificate2Collection with an imported certificate
+ protected static X509Certificate2Collection GetCertificateCollection(Configuration config)
+ {
+ var collection = new X509Certificate2Collection();
+ var flags = X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet;
+ if (config.Key != null)
+ collection.Import(config.Key, config.EffectivePassword, flags);
+ else
+ collection.Import(config.EffectiveKeyFilePath, config.EffectivePassword, flags);
+ return collection;
+ }
}
}
diff --git a/CyberSource/Client/Configuration.cs b/CyberSource/Client/Configuration.cs
index 500a148..b5604e2 100644
--- a/CyberSource/Client/Configuration.cs
+++ b/CyberSource/Client/Configuration.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
namespace CyberSource.Clients
{
@@ -62,6 +63,7 @@ public class Configuration
private string logDirectory = null;
private string serverURL = null;
private string keyFilename = null;
+ private byte[] key = null;
private string password = null;
private string logFilename = null;
private int logMaximumSize = -1;
@@ -161,6 +163,15 @@ public string ServerURL
set { serverURL = value; }
}
+ ///
+ /// This is optional. When set, it reads key from memory rather than from file system
+ ///
+ public byte[] Key
+ {
+ get { return key; }
+ set { key = value; }
+ }
+
///
/// Corresponds to [cybs.][merchantID].keyFilename.
///
@@ -380,6 +391,18 @@ internal string EffectiveKeyFilename
}
}
+ ///
+ /// Return the key file path that will take effect given
+ /// the current state of this Configuration object.
+ ///
+ internal string EffectiveKeyFilePath
+ {
+ get
+ {
+ return Path.Combine(KeysDirectory, EffectiveKeyFilename);
+ }
+ }
+
///
/// Returns the password that will take effect given
/// the current state of this Configuration object.
diff --git a/CyberSource/Client/NVPClient.cs b/CyberSource/Client/NVPClient.cs
index 3c9cbd7..92d89a4 100644
--- a/CyberSource/Client/NVPClient.cs
+++ b/CyberSource/Client/NVPClient.cs
@@ -80,13 +80,12 @@ public static Hashtable RunTransaction(
string keyFilePath = Path.Combine(config.KeysDirectory, config.EffectiveKeyFilename);
- proc.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
+ proc.ClientCredentials.ClientCertificate.Certificate = GetCertificate(config);
proc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
// Changes for SHA2 certificates support
- X509Certificate2Collection collection = new X509Certificate2Collection();
- collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
+ X509Certificate2Collection collection = GetCertificateCollection(config);
foreach (X509Certificate2 cert1 in collection)
{
diff --git a/CyberSource/Client/SoapClient.cs b/CyberSource/Client/SoapClient.cs
index 139295f..8717e99 100644
--- a/CyberSource/Client/SoapClient.cs
+++ b/CyberSource/Client/SoapClient.cs
@@ -79,15 +79,13 @@ public static ReplyMessage RunTransaction(
currentBinding.SendTimeout = timeOut;
//add certificate credentials
- string keyFilePath = Path.Combine(config.KeysDirectory,config.EffectiveKeyFilename);
- proc.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(keyFilePath,config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
+ proc.ClientCredentials.ClientCertificate.Certificate = GetCertificate(config);
+
+ proc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
+
+ // Changes for SHA2 certificates support
+ X509Certificate2Collection collection = GetCertificateCollection(config);
- proc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
-
- // Changes for SHA2 certificates support
- X509Certificate2Collection collection = new X509Certificate2Collection();
- collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
-
foreach (X509Certificate2 cert1 in collection)
{
if (cert1.Subject.Contains(config.MerchantID))
diff --git a/CyberSource/Client/XmlClient.cs b/CyberSource/Client/XmlClient.cs
index 51a9bc8..0f32eb4 100644
--- a/CyberSource/Client/XmlClient.cs
+++ b/CyberSource/Client/XmlClient.cs
@@ -84,13 +84,11 @@ public static XmlDocument RunTransaction(
XmlDocument doc = SoapWrap(request, nspace);
//Get the X509 cert and sign the SOAP Body
- string keyFilePath = Path.Combine(config.KeysDirectory, config.EffectiveKeyFilename);
X509Certificate2 cert = null;
X509Certificate2 cybsCert = null;
- X509Certificate2Collection collection = new X509Certificate2Collection();
- collection.Import(keyFilePath, config.EffectivePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
+ X509Certificate2Collection collection = GetCertificateCollection(config);
foreach (X509Certificate2 cert1 in collection)
{