Get Timestamp of signature in X509Certificate in C# - c#

Where can I get the date and the time of a signature?
Now I get the certificate information with this code:
var signer = X509Certificate2.CreateFromSignedFile(fileName);
var certificate = new X509Certificate2(signer);
And I can read some properties, but I cannot find WHEN the file was signed.
Thank you

Related

Equalivent for openssl s_client -connect <hostname>:<port> in C#

When I execute a openssl command to connect a particular server [myadda.tie.fire.glass.... dummy server name] , it gives me some output.
openssl s_client -connect myadda.tie.fire.glass:443
It gives me some output which contains information like
server certificate
issuer information
And another command which required the certificate from above command to provide me details info about the certificate.
openssl x509 -in <Certificate_FileName.crt> -text -nout
It gives me output as information about the certificate
issued for server
Validity
I want similar kind of output using some C# classes. I am not sure how to solve this query. Can anyone help me out?
Well below code help me to retrieve the required information.
X509Certificate2 cert = null;
var client = new TcpClient(host, 443);
var certValidation = new RemoteCertificateValidationCallback(delegate (object snd, X509Certificate certificate, X509Chain chainLocal, SslPolicyErrors sslPolicyErrors)
{
//Accept every certificate, even if it's invalid
return true;
});
// Create an SSL stream and takeover client's stream
using (var sslStream = new SslStream(client.GetStream(), true, certValidation))
{
sslStream.AuthenticateAsClient(host);
var serverCertificate = sslStream.RemoteCertificate;
cert = new X509Certificate2(serverCertificate);
//Convert Raw Data to Base64String
var certBytes = cert.Export(X509ContentType.Cert);
var certAsString = Convert.ToBase64String(certBytes, Base64FormattingOptions.None);
}
Here vertAsString gives me the certificate whereas cert gives me the other required information.

Loading X509Certificate2 certificate chain from store

I have a file (.p12) that contains 3 certificates (chained together) password-protected, that i have installed on my store.
I'm trying to load them to my code.
The way I load them from the file is like this:
var clientCert = new X509Certificate2(#"myfile.p12", "mypassword");
How can i achieve the same result while loading them from the store?
I've tried:
var computerCaStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
computerCaStore.Open(OpenFlags.ReadOnly);
var certificates = computerCaStore.Certificates.OfType<X509Certificate2>().ToLi‌​st();
var certFromStore = certificates.Single(c => c.Thumbprint == thumbprintMerchant);
var newCert = new X509Certificate2(certFromStore.RawData, "mypassword");
certFromStore should be equivalent to clientCert, the last line is what's breaking you.
The RawData property on X509Certificate2 returns the DER-encoded value for the certificate, not the original file bytes. A certificate does not have a private key, so the last line strips it away. Your question had previously mentioned a TLS exception, and that is because your cert no longer has a private key.
If certFromStore.HasPrivateKey is false, then whatever you did to put the certificate into the store didn't work the way you think it did. It's pretty unusual for a certificate with a private key to be in the Root store.

Get string from X509 Cert pfx file

I want to get the x509 certificate as a string (certString)
so that I can use it like
var cert = new X509Certificate2(Convert.FromBase64String(certString));
to generate a CertObject in Code.
I have tried around with certUtil but I dont know exactly which string I need.
Which string do I need to extract from the pfx data to be able to generate the X509 Certificate object in Code?
Here is the full code sample:
var cert = new X509Certificate2(#"c:\myCert.pfx", "password");
var certBytes = cert.RawData;
var certString = Convert.ToBase64String(certBytes);
All you need to do is converting it to byte[] then base64 string:
ConvertCertToBase64(cert.RawData);
private string ConvertCertToBase64(byte[] certRawData)
{
return Convert.ToBase64String(certRawData);
}

Generating passbook pass signature file in C#

App is about generating passes (Passbook App in Iphone) through C#.
I have downloaded Pass certificate and AppleWWDRCA certificate.
To generate pass I am able to generate pass.json and manifest.json.
But when I generate a PKCS 7 detached signature file using signing certificates and manifest.json it is not getting recognized by Passbook app in iphone.
I generated detached signature file using openssl in MAC and that is working fine and getting installed in Passbook.
I have downloaded pass certificate and AppleWWDRCA certificate
Can anyone help me in step by step procedure of creating signature file in c# and methods to be used
I have stored both the certificates in local folder not in windows local store. I have tried in windows local store before but it was not working.
below is the method used for signature,
X509Certificate2 card = GetCertificate(); //Fetches the pass certificate
X509Certificate2 appleCA = GetAppleCertificate(); //Fetches the AppleWWDRCA certificate
byte[] manifestbytes = Encoding.ASCII.GetBytes(manifest);
ContentInfo contentinfo = new ContentInfo(manifestbytes);
SignedCms signedCms = new SignedCms(contentinfo, true);
var signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber,card);
signer.Certificates.Add(new X509Certificate2(appleCA));
signer.IncludeOption = X509IncludeOption.WholeChain;
signer.SignedAttributes.Add(new Pkcs9SigningTime());
signedCms.ComputeSignature(signer);
signatureFile = signedCms.Encode();
return signatureFile;
I have created an open source C# library for generating these passes.
https://github.com/tomasmcguinness/dotnet-passbook
This is the code I use perform the signing of the files (it uses BouncyCastle)
// Load your pass type identifier certificate
X509Certificate2 card = GetCertificate(request);
Org.BouncyCastle.X509.X509Certificate cert = DotNetUtilities.FromX509Certificate(card);
Org.BouncyCastle.Crypto.AsymmetricKeyParameter privateKey = DotNetUtilities.GetKeyPair(card.PrivateKey).Private;
// Load the Apple certificate
X509Certificate2 appleCA = GetAppleCertificate(request);
X509.X509Certificate appleCert = DotNetUtilities.FromX509Certificate(appleCA);
ArrayList intermediateCerts = new ArrayList();
intermediateCerts.Add(appleCert);
intermediateCerts.Add(cert);
Org.BouncyCastle.X509.Store.X509CollectionStoreParameters PP = new Org.BouncyCastle.X509.Store.X509CollectionStoreParameters(intermediateCerts);
Org.BouncyCastle.X509.Store.IX509Store st1 = Org.BouncyCastle.X509.Store.X509StoreFactory.Create("CERTIFICATE/COLLECTION", PP);
CmsSignedDataGenerator generator = new CmsSignedDataGenerator();
generator.AddSigner(privateKey, cert, CmsSignedDataGenerator.DigestSha1);
generator.AddCertificates(st1);
CmsProcessable content = new CmsProcessableByteArray(manifestFile);
CmsSignedData signedData = generator.Generate(content, false);
signatureFile = signedData.GetEncoded();
I hope this helps.

Signing X509 Certs w/BouncyCastle - invalid digital signature [duplicate]

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Generated signed X.509 client certificate is invalid (no certificate chain to its CA)
I followed the example at:
http://www.bouncycastle.org/wiki/display/JA1/X.509+Public+Key+Certificate+and+Certification+Request+Generation
But the resulting signed client certificate has the following error when opened in windows:
"This file is invalid for use as the following: Security Certificate"
If I install it anyway and view it with certmgr, the certification path looks OK - I see my self-signed Certificate Authority (which is fine, no problems there) but the client cert has the following status:
"This certificate has an invalid digital signature."
If I call X509Certificate.Verify() it throws the following exception:
"Public key presented not for certificate signature"
Yet I'm using the same exact public key extracted from the Pkcs10CertificationRequest and when I called Verify() on that it's fine.
Any ideas? After days of struggling through this, I've got all the pieces working except this last one - and what's really confusing is that my self-signed CA cert is fine. There's just something going on with the client cert. Here's the entire block of code:
TextReader textReader = new StreamReader("certificaterequest.pkcs10");
PemReader pemReader = new PemReader(textReader);
Pkcs10CertificationRequest certificationRequest = (Pkcs10CertificationRequest)pemReader.ReadObject();
CertificationRequestInfo certificationRequestInfo = certificationRequest.GetCertificationRequestInfo();
SubjectPublicKeyInfo publicKeyInfo = certificationRequestInfo.SubjectPublicKeyInfo;
RsaPublicKeyStructure publicKeyStructure = RsaPublicKeyStructure.GetInstance(publicKeyInfo.GetPublicKey());
RsaKeyParameters publicKey = new RsaKeyParameters(false, publicKeyStructure.Modulus, publicKeyStructure.PublicExponent);
bool certIsOK = certificationRequest.Verify(publicKey);
// public key is OK here...
// get the server certificate
Org.BouncyCastle.X509.X509Certificate serverCertificate = DotNetUtilities.FromX509Certificate(System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile("servermastercertificate.cer"));
// get the server private key
byte[] privateKeyBytes = File.ReadAllBytes("serverprivate.key");
AsymmetricKeyParameter serverPrivateKey = PrivateKeyFactory.CreateKey(privateKeyBytes);
// generate the client certificate
X509V3CertificateGenerator generator = new X509V3CertificateGenerator();
generator.SetSerialNumber(BigInteger.ProbablePrime(120, new Random()));
generator.SetIssuerDN(serverCertificate.SubjectDN);
generator.SetNotBefore(DateTime.Now);
generator.SetNotAfter(DateTime.Now.AddYears(5));
generator.SetSubjectDN(certificationRequestInfo.Subject);
generator.SetPublicKey(publicKey);
generator.SetSignatureAlgorithm("SHA512withRSA");
generator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(serverCertificate));
generator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(publicKey));
var newClientCert = generator.Generate(serverPrivateKey);
newClientCert.Verify(publicKey); // <-- this blows up
return DotNetUtilities.ToX509Certificate(newClientCert).Export(X509ContentType.Pkcs12, "user password");
I figured this out. If you call X509Certificate.Verify(publicKey) you have to pass the CA's public key, not the client's public key from the Pkcs10CertificationRequest.

Categories

Resources