I have some code that is supposed to add an ssl certifacate to a port. It does say it has succesfully added a certificate, but when i host the website and then type in the localhost url (localhost:{port}) the page keeps loading. I don't understand why it doesn't work.
I already tried to host the website without ssl and that worked fine so that's not the problem.
public static class Certificate
{
public static void Standard(int port)
{
var certSubjectName = "HelloMyNameIsHank";
var expiresIn = TimeSpan.FromHours(1);
var cert = GenerateCert(certSubjectName, expiresIn);
Console.WriteLine("Generated certificate, {0}Thumbprint: {1}{0}", Environment.NewLine, cert.Thumbprint);
RegisterSslOnPort(port, cert.Thumbprint);
Console.WriteLine($"Registerd SSL on port: {port}");
}
private static void RegisterSslOnPort(int port, string certThumbprint)
{
var appId = Guid.NewGuid();
string arguments = $"http add sslcert ipport=0.0.0.0:{port} certhash={certThumbprint} appid={{{appId}}}";
ProcessStartInfo procStartInfo = new ProcessStartInfo("netsh", arguments);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
var process = Process.Start(procStartInfo);
while (!process.StandardOutput.EndOfStream)
{
string line = process.StandardOutput.ReadLine();
Console.WriteLine(line);
}
process.WaitForExit();
}
public static X509Certificate2 GenerateCert(string certName, TimeSpan expiresIn)
{
var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
var existingCert = store.Certificates.Find(X509FindType.FindBySubjectName, certName, false);
if (existingCert.Count > 0)
{
store.Close();
return existingCert[0];
}
else
{
var cert = CreateSelfSignedCertificate(certName, expiresIn);
store.Add(cert);
store.Close();
return cert;
}
}
public static X509Certificate2 CreateSelfSignedCertificate(string subjectName, TimeSpan expiresIn)
{
// create DN for subject and issuer
var dn = new CX500DistinguishedName();
dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);
// create a new private key for the certificate
CX509PrivateKey privateKey = new CX509PrivateKey();
privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0";
privateKey.MachineContext = true;
privateKey.Length = 2048;
privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; // use is not limited
privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
privateKey.Create();
// Use the stronger SHA512 hashing algorithm
var hashobj = new CObjectId();
hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY,
AlgorithmFlags.AlgorithmFlagsNone, "SHA512");
// add extended key usage if you want - look at MSDN for a list of possible OIDs
var oid = new CObjectId();
oid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL server
var oidlist = new CObjectIds();
oidlist.Add(oid);
var eku = new CX509ExtensionEnhancedKeyUsage();
eku.InitializeEncode(oidlist);
// Create the self signing request
var cert = new CX509CertificateRequestCertificate();
cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, "");
cert.Subject = dn;
cert.Issuer = dn; // the issuer and the subject are the same
cert.NotBefore = DateTime.Now;
// this cert expires immediately. Change to whatever makes sense for you
cert.NotAfter = DateTime.Now.Add(expiresIn);
cert.X509Extensions.Add((CX509Extension)eku); // add the EKU
cert.HashAlgorithm = hashobj; // Specify the hashing algorithm
cert.Encode(); // encode the certificate
// Do the final enrollment process
var enroll = new CX509Enrollment();
enroll.InitializeFromRequest(cert); // load the certificate
enroll.CertificateFriendlyName = subjectName; // Optional: add a friendly name
string csr = enroll.CreateRequest(); // Output the request in base64
// and install it back as the response
enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate,
csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // no password
// output a base64 encoded PKCS#12 so we can import it back to the .Net security classes
var base64encoded = enroll.CreatePFX("", // no password, this is for internal consumption
PFXExportOptions.PFXExportChainWithRoot);
// instantiate the target class with the PKCS#12 data (and the empty password)
return new System.Security.Cryptography.X509Certificates.X509Certificate2(
System.Convert.FromBase64String(base64encoded), "",
// mark the private key as exportable (this is usually what you want to do)
System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable
);
}
}
I want to be able to host my website with https. If anyone knows why this doesn't work please tell me.
I'm using httplistener for hosting. I don't want to use ASP.NET and/or IIS.
I'm not to familiar with ssl certificates so I would also really appreciate some code snippets even if it's just pseudo-code.
Related
I create a self sign certificate in debug with .net core and store it into the certificate store (my/root). When the app runs under windows the certificate cain is okay but under linux (ubuntu) the certificate chain check fails.
Certificate creation code is:
public static X509Certificate2 BuildSelfSignedServerCertificate()
{
using RSA rsa = RSA.Create(2048);
var request = new CertificateRequest("CN=My_Certificate",
rsa,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment |
X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false));
request.CertificateExtensions
.Add(new X509SubjectKeyIdentifierExtension(request.PublicKey, false));
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection {
new Oid("1.3.6.1.5.5.7.3.1"),
new Oid("1.3.6.1.5.5.7.3.2") }, false));
var certificate = request.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow.AddDays(-1)),
new DateTimeOffset(DateTime.UtcNow.AddDays(3650)));
LogFileLevelInformation("Created new self sign certificate.");
return certificate;
}
Then I add the certificate at my and root stores:
public static void CreateCert()
{
var certificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
certificateStore.Open(OpenFlags.ReadWrite);
bool result = certificateStore.Certificates.OfType<X509Certificate2>()
.Any(cert => cert.Subject.Contains("My_Certificate"));
if (result)
return;
var cert = BuildSelfSignedServerCertificate();
certificateStore.Add(cert);
certificateStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser, OpenFlags.MaxAllowed);
certificateStore.Open(OpenFlags.MaxAllowed);
certificateStore.Add(cert);
LogFileLevelInformation("New certificate added to store.");
}
then later I verify the chain:
private X509Certificate2 VerifyCertificateChain(X509Certificate2 certificate)
{
var chain = new X509Chain();
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
var chainBuilt = chain.Build(certificate);
if (chainBuilt)
{
LogDebugLevelInformation("The certificate chain is validated.")
return certificate;
}
return null;
}
the certificate check under windows with
var chainBuilt = chain.Build(certificate);
returns with result true, but when the same code runs under linux it returns false.
the certificate is available on linux under:
/root/.dotnet/corefx/cryptography/x509stores/root
and
/root/.dotnet/corefx/cryptography/x509stores/my
chain.StatusCode = "unable to get local issuer certificate"
Any idea why it is failing under linux?
I have an issue attempting to register a second device through DPS to an IoT Hub using x509 certificates. My root certificate authority is present and validated on both the DPS and IoT Hub (generated through openssl). As for the client side certificate, I'm generating it once the application starts (if to doesn't already exist) in the below code. What's bothering me is every single device gets enrolled into Azure DPS correctly but only the FIRST device gets authorized and registered. Is it possibly something I'm doing during my client side certificate creation that is messing it up? Also the error is found in this line during device registration to the IoT Hub:
DeviceRegistrationResult result = await provisioningDeviceClient.RegisterAsync().ConfigureAwait(false);
Added error:
2019/12/16 09:37:38.309|ERROR| Error found attempting to start service The device failed to register # the IoT Hub : The device failes to provision correctly: AMQP transport exception | Tidel.DeviceAgent.DeviceAgent |
CLIENT SIDE CERTIFICATE GENERATION
X509Certificate2 caRootCertificate;
X509Store caStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
caStore.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection signerCollection = (X509Certificate2Collection)caStore.Certificates.Find(X509FindType.FindByIssuerName, "CERTNAME", true);
caStore.Close();
if (signerCollection.Count != 0)
{
caRootCertificate = signerCollection[0];
using (var rsa = RSA.Create())
{
rsa.KeySize = 2048;
var clientCertificateRequest = new CertificateRequest($"CN={_writableOptions.Value.RegistrationId}", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
clientCertificateRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
var issuerSubjectKey = caRootCertificate.Extensions["Subject Key Identifier"].RawData;
var segment = new ArraySegment<byte>(issuerSubjectKey, 2, issuerSubjectKey.Length - 2);
var authorityKeyIdentifier = new byte[segment.Count + 4];
authorityKeyIdentifier[0] = 0x30;
authorityKeyIdentifier[1] = 0x16;
authorityKeyIdentifier[2] = 0x80;
authorityKeyIdentifier[3] = 0x14;
segment.CopyTo(authorityKeyIdentifier, 4);
clientCertificateRequest.CertificateExtensions.Add(new X509Extension("2.5.29.35", authorityKeyIdentifier, false));
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddDnsName(_writableOptions.Value.RegistrationId);
var sanExtension = sanBuilder.Build();
clientCertificateRequest.CertificateExtensions.Add(sanExtension);
clientCertificateRequest.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.2") }, false));
clientCertificateRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(clientCertificateRequest.PublicKey, false));
var notBefore = DateTimeOffset.UtcNow.AddDays(-1);
if (notBefore < caRootCertificate.NotBefore)
{
notBefore = new DateTimeOffset(caRootCertificate.NotBefore);
}
var notAfter = DateTimeOffset.UtcNow.AddDays(365);
if (notAfter > caRootCertificate.NotAfter)
{
notAfter = new DateTimeOffset(caRootCertificate.NotAfter);
}
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var unixTime = Convert.ToInt64((DateTime.UtcNow - epoch).TotalSeconds);
var serial = BitConverter.GetBytes(unixTime);
using (var cert = clientCertificateRequest.Create(caRootCertificate, notBefore, notAfter, serial))
{
X509Certificate2 client = cert.CopyWithPrivateKey(rsa);
return await Task.FromResult(client);
}
}
}
else
{
throw new FileNotFoundException($"Could not find a root certificate.");
}
DEVICE ENROLLMENT TO DPS
Attestation attestation = X509Attestation.CreateFromClientCertificates(new X509Certificate2(certificate.Export(X509ContentType.Cert)));
IndividualEnrollment individualEnrollment = new IndividualEnrollment(_writableOptions.Value.RegistrationId, attestation)
{
DeviceId = _writableOptions.Value.DeviceId,
ProvisioningStatus = ProvisioningStatus.Enabled
};
individualEnrollmentResult = await _provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false);
DEVICE REGISTRATION TO IOT HUB
using (var certificatePassword = new X509Certificate2(certificate.GetRawCertData(), _writableOptions.Value.CertPass))
{
using (var security = new SecurityProviderX509Certificate(certificatePassword))
{
using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly))
{
ProvisioningDeviceClient provisioningDeviceClient = ProvisioningDeviceClient.Create(_writableOptions.Value.AzureEndpoint, _writableOptions.Value.IdScope, security, transport);
DeviceRegistrationResult result = await provisioningDeviceClient.RegisterAsync().ConfigureAwait(false);
IAuthenticationMethod authenticationMethod = new DeviceAuthenticationWithX509Certificate(result.DeviceId, certificate);
DeviceClient deviceClient = DeviceClient.Create(result.AssignedHub, authenticationMethod, TransportType.Amqp_Tcp_Only);
return await Task.FromResult(deviceClient);
}
}
}
I figured out the issue. When the certificate was generated in the store, I was using FindByIssuerName to locate the certificate.
X509Certificate2Collection signerCollection = (X509Certificate2Collection)caStore.Certificates.Find(X509FindType.FindByIssuerName, "CERTNAME", true);
After investigating further, there were TWO certificates with the exact same name in the store. The issue: MMC snap-in was only showing one certificate. After looking around, it was suggested somewhere to run a storerepair command on the store. After running the store repair command, I could then see both certificates in MMC and was able to remove the offending certificate preventing the valid one from being detected.
Windows Version: Windows Embedded 8.1 Industry Pro
I want to consume a web service (https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list) and as per there documentation (https://realtime-listings.webservices.zpg.co.uk/docs/latest/documentation.html)
I have to send .crt and .pem file for authentication.
I am able to load .crt file but for .pem I am getting error that Cannot find the requested object . I have tried different method to load PEM file.
I have followed following threads but still not able to load X509Certificate from .pem file.
My code is as below
var webAddr = "https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application/json; profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.1/schemas/listing/list.json";
httpWebRequest.Method = "POST";
httpWebRequest.ClientCertificates.Add(X509Certificate.CreateFromCertFile(#"E:\ProcessZooplaData\zpg_realtime_listings_14810206-20261204.crt"));
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Now till here everything is Okay now If I try to load .pem file then I am getting error
var pem = System.IO.File.ReadAllText(#"E:\\ProcessZooplaData\\private.pem");
byte[] certBuffer = GetBytesFromPEM(pem, "RSA PRIVATE KEY");
var certificate = new X509Certificate(certBuffer);
httpWebRequest.ClientCertificates.Add(certificate);
byte[] GetBytesFromPEM(string pemString, string section)
{
var header = String.Format("-----BEGIN {0}-----", section);
var footer = String.Format("-----END {0}-----", section);
var start = pemString.IndexOf(header, StringComparison.Ordinal);
if (start < 0)
return null;
start += header.Length;
var end = pemString.IndexOf(footer, start, StringComparison.Ordinal) - start;
if (end < 0)
return null;
return Convert.FromBase64String(pemString.Substring(start, end));
}
I am getting error here that Cannot find the requested object .
Rest of code is as below
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"branch_reference\":\"test\"}";
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//return result;
}
I have tried following threads for reference
how to get private key from PEM file?
http://pages.infinit.net/ctech/20040812-0816.html
If your certificate has already been loaded into your cert store, then you can do the following:
var requestHandler = new WebRequestHandler();
var store = new X509Store("My", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, certificateName, true);
if (certificates.Count > 0)
requestHandler.ClientCertificates.Add(certificates[0]);
else
throw new Exception(string.Format("Can't find certificate {0}", certificateName));
using (var client = new HttpClient(requestHandler))
{
do work!
}
which should add the cert from the store to the connection.
Then you'll need to open up the cert store in the Certificates (run mmc, add Certificates to the console for the local computer store), browse to your certificate, right click it and select All Tasks > Manage Private Keys and grant the user account your application will run under "read" access to the cert's private key and you won't need to open any files to do this.
Of course, if you're doing this on a shared hosting environment where you don't get access to the certs or can't install them into the cert store, that's a different problem.
I am working with creating X509Certificate2 certificate in my C#.net application. While creating certificate, how to set the issuer name? currently issuer name shows same as subject name.
Please help.
Hmm.
Finally I have used Bouncy Castle dll to create certificates.Using this, there is a method to set issuer name.
This is the fully code to generate x509Certificate and to store into Trusted People store:
private X509Certificate2 GeneratePFXFile(string certificate,string company,string email,string state,string locality,string username,string country)
{
X509Certificate2 cert = null;
try
{
var kpgen = new RsaKeyPairGenerator();
kpgen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));
var kp = kpgen.GenerateKeyPair();
var gen = new X509V3CertificateGenerator();
var certName = new X509Name("CN=" + certificate);
var issuer = new X509Name("C="+country+",O="+company+",OU=LBC Mundial Corp.USA,E="+email+",L="+locality+",ST="+state);
var serialNo = BigInteger.ProbablePrime(120, new Random());
gen.SetSerialNumber(serialNo);
gen.SetSubjectDN(certName);
gen.SetIssuerDN(issuer);
gen.SetNotAfter(DateTime.Now.AddYears(50));
gen.SetNotBefore(DateTime.Now);
gen.SetSignatureAlgorithm("MD5WithRSA");
gen.SetPublicKey(kp.Public);
gen.AddExtension(
X509Extensions.AuthorityKeyIdentifier.Id,
false,
new AuthorityKeyIdentifier(
SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public),
new GeneralNames(new GeneralName(certName)),
serialNo));
gen.AddExtension(
X509Extensions.ExtendedKeyUsage.Id,
false,
new ExtendedKeyUsage(new ArrayList() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1") }));
var newCert = gen.Generate(kp.Private);
byte[] pfx = DotNetUtilities.ToX509Certificate(newCert).Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pfx, (string)null);
X509Store store = new X509Store((StoreName)StoreName.TrustedPeople, (StoreLocation)StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
cert = new X509Certificate2(pfx,(string)null, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);
store.Add(cert);
store.Close();
}
catch (Exception ex)
{
ShowError(ex.Message);
return null;
}
return cert;
}
I working with programmatically working with certificates and communicating with a Certificate Authority. I have been working with the CertClient and CertEnroll COM objects in C# on Windows 2008R2.
I can generate a request and get back a cert from the CA. I started with this example:
http://blogs.msdn.com/b/alejacma/archive/2008/09/05/how-to-create-a-certificate-request-with-certenroll-and-net-c.aspx
I am having two issues that I can not figure out. First is, how can I get access to the private key that was used to generate the cert? The methods that are part of the IX509PrivateKey interface don't seem to work on my test env. The request I give the CA is different from the private key, correct?
The second issue is I can't seem to figure out to supply an enrollment agent cert when requesting a cert. The older versions of this API had a method, SetSignerCertificate, that was used. I can't find an equivalent in the new API.
An example using an Enrollment Agent certificate is found on MSDN under Create Enroll on Behalf of Another User Request. The certificate will be installed into the certificate store you specify, and you can utilize the private key as you would any other installed certificate.
Full example:
// Add references to CERTENROLL (CertEnroll 1.0 Type Library)
// and CERTCLILib (CertCli 1.0 Type Library)
using CERTCLILib;
using CERTENROLLLib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using X509KeyUsageFlags = CERTENROLLLib.X509KeyUsageFlags;
namespace TestSubmitEnrollment
{
class Program
{
static void Main(string[] args)
{
string requesterName = #"DOMAIN\otherUser";
string caName = #"CA1.DOMAIN.LOCAL\DOMAIN-CA1-CA";
string template = "User";
// signerCertificate's private key must be accessible to this process
var signerCertificate = FindCertificateByThumbprint("3f817d138f32a9a8df2aa6e43b8aed76eb93a932");
// create a new private key for the certificate
CX509PrivateKey privateKey = new CX509PrivateKey();
// http://blogs.technet.com/b/pki/archive/2009/08/05/how-to-create-a-web-server-ssl-certificate-manually.aspx
privateKey.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";
privateKey.MachineContext = false;
privateKey.Length = 2048;
privateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE;
privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_NONE;
privateKey.Create();
// PKCS 10 Request
// we use v1 to avoid compat issues on w2k8
IX509CertificateRequestPkcs10 req = (IX509CertificateRequestPkcs10)new CX509CertificateRequestPkcs10();
req.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, privateKey, template);
// PKCS 7 Wrapper
var signer = new CSignerCertificate();
signer.Initialize(false, X509PrivateKeyVerify.VerifyAllowUI, EncodingType.XCN_CRYPT_STRING_BASE64_ANY,
Convert.ToBase64String(signerCertificate.GetRawCertData()));
var wrapper = new CX509CertificateRequestPkcs7();
wrapper.InitializeFromInnerRequest(req);
wrapper.RequesterName = requesterName;
wrapper.SignerCertificate = signer;
// get CSR
var enroll = new CX509Enrollment();
enroll.InitializeFromRequest(wrapper);
var csr = enroll.CreateRequest();
//File.WriteAllText("csr.p7b", csr);
// submit
const int CR_IN_BASE64 = 1, CR_OUT_BASE64 = 1;
const int CR_IN_PKCS7 = 0x300;
ICertRequest2 liveCsr = new CCertRequest();
var disposition = (RequestDisposition)liveCsr.Submit(CR_IN_BASE64 | CR_IN_PKCS7, csr, null, caName);
if (disposition == RequestDisposition.CR_DISP_ISSUED)
{
string resp = liveCsr.GetCertificate(CR_OUT_BASE64);
//File.WriteAllText("resp.cer", resp);
// install the response
var install = new CX509Enrollment();
install.Initialize(X509CertificateEnrollmentContext.ContextUser);
install.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedRoot,
resp, EncodingType.XCN_CRYPT_STRING_BASE64_ANY, null);
}
else
{
Console.WriteLine("disp: " + disposition.ToString());
}
Console.WriteLine("done");
Console.ReadLine();
}
private enum RequestDisposition
{
CR_DISP_INCOMPLETE = 0,
CR_DISP_ERROR = 0x1,
CR_DISP_DENIED = 0x2,
CR_DISP_ISSUED = 0x3,
CR_DISP_ISSUED_OUT_OF_BAND = 0x4,
CR_DISP_UNDER_SUBMISSION = 0x5,
CR_DISP_REVOKED = 0x6,
CCP_DISP_INVALID_SERIALNBR = 0x7,
CCP_DISP_CONFIG = 0x8,
CCP_DISP_DB_FAILED = 0x9
}
private static X509Certificate2 FindCertificateByThumbprint(string sslCertThumbprint)
{
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindByThumbprint, sslCertThumbprint, true);
if (certs.Count > 0)
{
return certs[0];
}
else
{
throw new KeyNotFoundException();
}
}
finally
{
store.Close();
}
}
// we re-declare this to account for backcompat to 2k8
[ComImport, Guid("884E2042-217D-11DA-B2A4-000E7BBB2B09")]
class CX509CertificateRequestPkcs10
{
}
}
}
The request I give the CA is different from the private key, correct?
You only pass the public key to the CA.
I can't seem to figure out to supply an enrollment agent cert when requesting a cert.
You Need to wrap the PKCS10 in a CMS/CMC. Have a look here https://www.rfc-editor.org/rfc/rfc5272