LdapConnection differences between JAVA and C# - c#

I am currently trying to convert a Java code into C# in order to establish a SSL LDAP connection.
In Java, I can specify the certificate's location with the following: System.setProperty("javax.net.ssl.trustStore", "D:\\xnet\\ldap\\cacerts");
What is the equivalent in C# ? How can I specify where the certificate is ? (LdapConnection.ClientCertificates being read-only)
Thank you very much

The ClientCertificates property is a CertificateCollection instance, you should be able to add a certificate to this collection:
connection.ClientCertificates.Add(myCert);
The X509Certificate would need to be loaded youself, normally from one of the Windows certificate stores, see this page on MSDN for details on how to load a certificate.

Related

UWP Application PIV Example Needed

We are developing a C# UWP application using Visual Studio 2019. I have successfully setup monitoring of the YubiKey FIPS (4.4.5 firmware) being inserted/removed from the USB port. We setup the YubiKey to use PIV and have loaded a certificate into slot 9c (using YubiKey PIV Manager, I have not installed the mini driver). I do note that when the YubiKey is inserted into the USB, it auto loads my personal cert store with the certificate that is in slot 9c. We receive a challenge from our server and I need to use it to verify against the YubiKey. What is the next step to get the certificate from slot 9c (what if you have multiple certs on that key)? Yubico does not have an example showing how to integrate the key with an app (I don't believe Windows Hello is applicable here, no?). We are trying to use the Windows.Devices.SmartCards namespace. This namespace does not seem to have the concept of slots. Is that the correct direction or do we need to use Yubico libraries (mini driver) I'm not aware. The documentation is limited.
var yubiKeys = Readers.Where(r => r.Value.Name.Contains("Yubi", StringComparison.OrdinalIgnoreCase));
foreach (KeyValuePair<string, SmartCardReader> item in yubiKeys)
{
IReadOnlyList<SmartCard> cards = await item.Value.FindAllCardsAsync();
foreach(SmartCard card in cards)
{
SmartCardProvisioning prov = await SmartCardProvisioning.FromSmartCardAsync(card);
using (SmartCardChallengeContext context = await prov.GetChallengeContextAsync())
{
IBuffer yubiKeyChallenge = context.Challenge; // IS THIS THE CARDS ADMIN PIN?
// Challenge to acquire cert here perhaps?
// the card object has no concept of slots, would each slot be a card in the reader?
// if so, how would I use the Challenge for that card?
}
}
}
The Windows Smart Card components (including the Windows Inbox Smart Card Minidriver and the Yubico minidriver) don’t directly implement supported PIV concepts like slots or objects. Instead, the minidriver scans the PIV slots and converts any present keys to "key containers", which is how Windows deals with private keys and certificates. Each certificate in the Certificate Store has an associated key container, but since it has no concept of PIV, details like the key reference slot have been abstracted away.
As with most built-in Windows components, the app doesn’t talk to the smart card directly, instead it uses the certificate that the Certificate Propagation service adds to the personal store.
If you inspect the user's personal store with Certificate Manager (certmgr.msc), the certificate properties should have a note that you have a private key associated with the certificate.
To sign or encrypt with the private key, the app acquires the
certificate from the personal store and uses the appropriate .NET CSP
with that certificate.
In general, UWP apps have limited native interop capabilities and rely on using the rudimentary APIs of the smart card key storage provider (KSP) to later be called through the CNG interface.
Here’s an example of using the UserCertificateStore to interact with certificates within the user’s personal certificate store.
You can then use that certificate with your favorite CSP software library to sign or encrypt. A few examples here.
To access smartcard or usb token content like slots, keys in it, directly you may need to use PKCS#11.
But since you said smartcard content is being loaded by smartcard driver (CSP) to Windows Certificate store, you may use Windows.Security, X509 certificates and RSA Provider (I don't remember .NET namespaces exactly...) to give signing request using RSAProvider and CSP would in turn send that request to smartcard. You many not need to access smartcard directly for signing.
For browser based user authentication, please refer to so answer

WCF Message Encryption with in memory x509Certificate2 Certificate

I would like to be able to use a certificate that I have in memory and not from the "Current User" or "Current Machine" certificate store.
Our desire is to have multiple WCF clients (with the same service) that we connect to and store their public key in a database. Then, by some convention, pick which certificate to encrypt the message with. I do not want to have this stored in the Web.config nor have it stored in the local machines keystore. We are needing this to be agnostic of where it is deployed (Azure vs on-prem vs whatever).
I know that this would work:
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.CurrentUser, StoreName.TrustedPeople, X509FindType.FindByThumbprint, cert.Thumbprint);
But I want to do:
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(x509Certificate);
Is this possible for an app to have it's own keystore, like in Java?
X509CertificateRecipientClientCredential defines a DefaultCertificate property which is settable.
According to http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Security/X509CertificateRecipientClientCredential.cs,eaccbfb7a59b7226,references the property sets the same backing field as SetDefaultCertificate.

Using C#, how to programmatically determine if a certificate in a Windows certificate store has been disabled

I'm currently working on refining communications between mutually authenticated client/server applications using HTTPS. I am currently building validation logic into a C# client to help identify configuration issues when a TLS connection fails. In verifying the connection, I validate that the root CA certificate presented by the server is installed on the client, in the appropriate store, and is valid. I'm using X509Store to pull the X509Certificate2, and validating it using X509Chain.
My issue is that the certificate will report as valid even if the certificate has been disabled via MMC. So the TLS connection will fail, despite the chain reporting as valid.
It's an unlikely case, but one I'd like to handle by reporting something like "Could not connect because root CA is disabled."
Could anyone point me in the direction of a .NET or Win32 call that could be made to determine the value of "Certificate Purposes" for a certificate? Or to read the "Certificate Status" for a cert?
I read through MSDN's listing of what's in the System.Security.Cryptography namespace, and started looking into CryptoAPI and CNG, but didn't find anything so far.
Thanks!
That dialog does not "disable" a certificate it disables it "for all purposes". What this means is it counts as having an empty Enhanced Key Usage extension for purposes of EKU validation.
Normally a root certificate (or an intermediate CA certificate) will not have an EKU extension, so if you do a chain build with any ApplicationPolicy value it will be a match. Once you set it to Disable for all purposes you'll get a chain error X509ChainStatusFlags.NotValidForUsage.
If you want to build something for validating TLS you'd check either the Server Authentication or Client Authentication EKUs (depending on what you're checking):
// Server EKU or Client EKU
Oid eku = forServer ? new Oid("1.3.6.1.5.5.7.3.1") : new Oid("1.3.6.1.5.5.7.3.2");
// Test if it's valid for that purpose
chain.ChainPolicy.ApplicationPolicy.Add(eku);
If you want to "Disable" a root CA altogether, add a copy of the certificate to the Disallowed store (called "Untrusted Certificates" in the UI). That will result in a chain build producing X509ChainStatusFlags.ExplicitDistrust.

load certificate in WP7

in WP7 I Tried to load certificate to get a public key from it and I use this
X509Certificate x509 = null;
x509 = X509Certificate.CreateFromCertFile(CertificateFilePath);
and I got this exception:
{System.MethodAccessException: Attempt to access the method failed:
System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile(System.String)
any one have an idea about this problem ? there anther way to read cert file in WP7 ?
This is an inherent limitation put in place because your application is running in a sandboxed environment, and therefore is not exactly an app that would be classified as "trusted" by Silverlight standards. To quote MSDN:
This member can be used only by trusted applications. If you try to
use this member in a partial-trust application, your code will throw a
MethodAccessException exception. This member is security-critical,
which restricts its use.

Can a .NET assembly be signed using an X509Certificate?

I believe I have a foundational understanding of the X509Certificate and have created certificates and private keys for my Development environment. Getting more acquainted now with the X509Certificate Class and other relevant permissions also.
So in the process, I decided to test a certificate after having installed it on my system. Then using the following code, I attempted to validate the check process for certification authentication:
const string x509Cert = #"\PathToMyCertificate\LMC.cer";
var cert = new X509Certificate(x509Cert);
var pmc = new PublisherMembershipCondition(cert);
if(pmc.Check(Assembly.GetCallingAssembly().Evidence))
{
Console.WriteLine("Assembly belongs to publisher");
}
Of course as expected, the inner block of code doesn't execute. So then I figured to simply sign my assembly using the certificate key, but "simply" wasn't as simple as I'd anticipated.
I used the following code in effort of assigning the certificate to my applications Evidence:
var publisher = new Publisher(X509Certificate.CreateFromCertFile(x509Cert));
var evidence = Assembly.GetCallingAssembly().Evidence;
evidence.AddHost(publisher);
// Create an identity permission based on publisher evidence.
var x509Permission = (PublisherIdentityPermission)publisher.CreateIdentityPermission(evidence);
x509Permission.Demand();
But this didn't seem to work either. Next, I checked the properties of my project to see if there was any way to sign it there using the X509Certificate key but nothing. The only option I see that comes close is to sign with Click Once manifests; but the "Select from file" option is looking for a .pfx extension. So I think maybe this method only works to support certificates generated by Click-Once?
Per BOL, "If you have a key file or certificate in another format, store it in the Windows certificate store and select the certificate is described in the previous procedure." I installed my X509Certificate in the Trusted Root Certificate Authorities store. Wouldn't that be a Windows certificate store? Because nothing shows up in the Certificate Store window.
Searching online resources didn't yield much either unless I am using the wrong combination of keywords. Now I could create another X509Certificate and key ensuring that the extension of the key is .pfx but I wanted to make certain that I am on the right course of resolve before spinning my wheels for nothing and I don't believe that would be the answer.
So, can a .NET assembly be signed using an X509Certificate? If so, what documentation is available to assist in performing this task?
Publisher* classes are associated with Authenticode(tm).
Look for the command-line tools:
* signcode (or signtool)
* chktrust
for how you can sign any .exe, .dll (and .cab, .ocx) using a valid code-signing certificate. A google search on Authenticode or "code-signing certificate" can also be helpful.
The question is what you want to do. There exist .NET signing (using RSA keypair) used for strong-naming the assemblies, and there exists Authenticode which lets you sign any file in PE format including assemblies in DLL files. Note, that Authenticode is not .NET-specific and knows nothing about .NET. It signs PE structure.
As said by poupou, for Authenticode signing (using X.509 certificates suitable for Code Signing) you can use SignTool.exe tool. .NET will verify the signature when it loads the assembly, but in some cases such verification can take extra seconds (if the OS performs CRL and OCSP checking of certificates in the chain), slowing down assembly loading.
So you need to choose the right tool and define what you want to achieve (signing is a method, not a goal).

Categories

Resources