Testing X509 Certificate Expiry date with C - c

How can I programaticlaly test if a X509 ?* certificate is expired or not ?
Is their a direct crypto api ?
or I have to get the not_after time and check it manually in my code ?

You didn't say which language so I was summing them up anyway:
php
$data = openssl_x509_parse(file_get_contents('/path/to/cert.crt'));
$validFrom = date('Y-m-d H:i:s', $data['validFrom_time_t']);
$validTo = date('Y-m-d H:i:s', $data['validTo_time_t']);
Java X509Certificate
InputStream inStream = null;
try (InputStream inStream = new FileInputStream("fileName-of-cert")) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
// check if valid on specific date (now set for today)
cert.checkValidity(new Date());
// Date nBefore = cert.getNotBefore();
// Date nAfter = cert.getNotAfter();
}
C++
using namespace System;
using namespace System::Security::Cryptography::X509Certificates;
int main()
{
// The path to the certificate.
String^ Certificate = "Certificate.cer";
// Load the certificate into an X509Certificate object.
X509Certificate^ cert = X509Certificate::CreateFromCertFile( Certificate );
// Get the value.
String^ results = cert->GetExpirationDateString();
// Display the value to the console.
Console::WriteLine( results );
}
C
X509 *x
time_t *ptime;
i=X509_cmp_time(X509_get_notBefore(x), ptime);
i=X509_cmp_time(X509_get_notAfter(x), ptime);

You should be able to use:
result=X509_cmp_time(X509_get_notBefore(cert), ptime);
and
result=X509_cmp_time(X509_get_notAfter(cert), ptime);
using OpenSSL. I'm not sure if you can get it less "manual" than that.

Related

Signing Both Message and Assertion with Java Saml from Onelogin

I am trying to follow this answer: https://stackoverflow.com/a/46000524/13925339
I can sign the SAML Response message:
String saml = "...";
String pubKeyBytes = "...";
String privKeyBytes = "...";
Document documentResponse = Util.loadXML(saml); //loads string to document
X509Certificate cert = null;
cert = Util.loadCert(pubKeyBytes);
PrivateKey privateKey = Util.loadPrivateKey(privKeyBytes);
//sign saml assertion:
String stringSignedResponse = Util.addSign(documentResponse, privateKey, cert, null);
I can pull out the SAML Assertion and sign that:
NodeList nodelist = documentResponse.getElementsByTagName("saml2:Assertion");
Node nodeSamlAssertion = nodelist.item(0);
String stringSignedSamlAssertion = Util.addSign(nodeSamlAssertion, privateKey, cert, null);
BUT how do I combine the two (as is possible with OneLogin's https://www.samltool.com/sign_response.php online tool in 'Sign Message and Assertion' mode)?
Worked out how to do this by
Turning the String returned from Util.addSign(nodeSamlAssertion,..) back into a Node
Importing that Node back into the SAML response Document object.
Using the Element.replaceChild method to switch the unsigned SAML Assertion node with the signed SAML Assertion node
Element nodeSignedSamlAssertion = DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(new ByteArrayInputStream(stringSignedSamlAssertion.getBytes()))
.getDocumentElement();
Node copiedNode = documentResponse.importNode(nodeSignedSamlAssertion, true);
documentResponse.getDocumentElement().replaceChild(copiedNode, documentResponse.getElementsByTagName("saml2:Assertion").item(0));

Got a timeout error when I send an email using gmail:ClientConnector in ballerinalang

I try to implement a program in ballerina to send an email using ballerina gmail:ClientConnector with gmail API. But it gives a timeout error like below.
error: ballerina.lang.errors:Error, message: failed to invoke 'post' action in ClientConnector. response was not received within sender timeout of 180 seconds
at ballerina.net.http:ClientConnector.post(<native>:0)
at org.wso2.ballerina.connectors.oauth2:ClientConnector.post(org/wso2/ballerina/connectors/oauth2/ClientConnector.bal:53)
at org.wso2.ballerina.connectors.gmail:ClientConnector.sendMail(org/wso2/ballerina/connectors/gmail/gmailConnector.bal:631)
at .:main(helloworld.bal:26)
And here is the code which I implement.
import org.wso2.ballerina.connectors.gmail;
function main (string[] args) {
string clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string userId = "webmisproject#gmail.com";
string accessToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string refreshToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
gmail:ClientConnector gmailConnector = create gmail:ClientConnector(userId,accessToken,refreshToken,clientId,clientSecret);
string to = "b.wathsala.bw#gmail.com";
string subject = "Test Mail";
string from = "webmisproject#gmail.com";
string messageBody = "Hello Buddhi";
string cc = "";
string bcc = "";
string id = "";
string threadId = "";
message gmailResponse;
gmailResponse = gmail:ClientConnector.sendMail(gmailConnector,to,subject,from,messageBody,cc,bcc,id,threadId);
}
I implement this code as in main function as well as a service in ballerina, but both give same error.As well it takes little bit time to give that error.
I solved that problem. I used UBUNTU 14.04. But when I run that code in UBUNTU 16.04 the issue was solved. So I think the problem is in UBUNTU 14.04. But I don't know what is the exact issue in UBUNTU 14.04.

Generating Chrome Packaged App .crx header with Java

I"m trying to build the header in Java with no luck.
(here is the spec: https://developer.chrome.com/extensions/crx)
Any ideas?
protected void geneateCrxHeader (OutputStream ins,byte[] zipArchive) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, InvalidKeyException, SignatureException{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();
byte[] key = pair.getPublic().getEncoded();
Signature instance = Signature.getInstance("SHA1withRSA");
instance.initSign(pair.getPrivate());
instance.update(zipArchive);
byte[] hash = instance.sign();
byte[] magic = {0x43,0x72,0x32,0x34,0x02,0x00,0x00,0x00,0x00,0x01,0x0E,0x0B,0x00,0x00,0x08,0x00};
ins.write(magic);
ins.write(key);
ins.write(hash);
}
and I get CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE..
I must be using wrong keygen.
in the docs they do say :
"..the contents of the author's RSA public key, formatted as an X509 SubjectPublicKeyInfo block. .."
i wonder if that is what i'm not doing correctly...
p.s Java crypto is a new frontier for me , so pls don't laugh if I did something totally dumb.
Here is some code that I whipped up and didn't test that illustrates producing just the header. I based this solely on reading the spec.
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Signature;
public static byte[] generateCrxHeader(byte[] extensionContents) throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = new SecureRandom();
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();
Signature sigInstance = Signature.getInstance("SHA1withRSA");
sigInstance.initSign(pair.getPrivate());
sigInstance.update(extensionContents);
byte [] signature = sigInstance.sign();
byte [] subjectPublicKeyInfo = pair.getPublic().getEncoded();
final int headerLength = 4 + 4 + 4 + 4 + subjectPublicKeyInfo.length + signature.length;
ByteBuffer headerBuf = ByteBuffer.allocate(headerLength);
headerBuf.order(ByteOrder.LITTLE_ENDIAN);
headerBuf.put(new byte[]{0x43,0x72,0x32,0x34}); // Magic number
headerBuf.putInt(2); // Version
headerBuf.putInt(subjectPublicKeyInfo.length); // public key length
headerBuf.putInt(signature.length); // signature length
headerBuf.put(subjectPublicKeyInfo);
headerBuf.put(signature);
final byte [] header = headerBuf.array();
return header;
}

Salted sha512 in C, cannot synchronise with Symfony2's FOSUserBundle

My developement is separated into two components :
The website, a Symfony application using FOSUserBundle, which encrypts password using SHA512, and a salt.
An authentication module, programmed in C, which should be able to reproduce the SHA512 salted hash once it's given the salt, and the cleartext password.
Some information about my environment
I'm using Linux Ubuntu 12.04.
ldd --version answers EGLIBC 2.15-0ubuntu10.4 2.15 (maybe I need 2.7 ? But apt-get is a real PAIN when it comes to upgrading packages correctly).
The crypt.h header files mentions #(#)crypt.h 1.5 12/20/96
The problem itself
My problem occurs in the authentication module : I'm unable to get the same hash as the one produced by Symfony's FOSUserBundle. Here's my example :
The password salt, used by Symfony, is bcccy6eiye8kg44scw0wk8g4g0wc0sk.
The password itself is test
With this information, Symfony stores this final hash :
fH5vVoACB4e8h1GX81n+aYiRkSWxeu4TmDibNChtLNZS3jmFKBZijGCXcfzCSJFg+YvNthxefHOBk65m/U+3OA==
Now, in my C authentication module, I run this piece of code (crypt.h is included) :
char* password = "test";
char* salt = "$6$bcccy6eiye8kg44scw0wk8g4g0wc0sk";
char* hash = malloc(256);
memset(hash, 0, 256);
encode64(crypt(password, salt), hash, strlen(password));
fprintf(stdout, "%s\n", hash);
(here is my base64 encoder : http://libremail.tuxfamily.org/sources/base64-c.htm)
And this outputs...
JDYkYg==
Which is completely different from my Symfony2 hash.
Browsing Stack Overflow, I found this question (Symfony2 (FOSUserBundle) SHA512 hash doesn't match C# SHA512 hash) written by someone encountering the same issue (with C# though). So I decided to run this test...
char* password = "test{bcccy6eiye8kg44scw0wk8g4g0wc0sk}";
char* salt = "$6$bcccy6eiye8kg44scw0wk8g4g0wc0sk"; // I tried without salt, or with "$6$" as well.
char* hash = malloc(256);
memset(hash, 0, 256);
encode64(crypt(password, salt), hash, strlen(password));
fprintf(stdout, "%s\n", hash);
Of course, it was a complete failure, I got :
JDYkYmNjY3k2ZWl5ZThrZzQ0cyRycmN6TnpJUXFOYU1VRlZvMA==
I've tried mixing the password and the salt in various ways, but I could never get the Symfony's salt in the authentication module. Is there something I've missed on the way ? Have I misunderstood the way Symfony's FOSUserBundle stores passwords ?
Not really an answer but I'm guessing you have not looked into how Symfony encodes passwords in any great detail? The encoding process is tucked away into an encoder object. For SHA512 we use:
namespace Symfony\Component\Security\Core\Encoder;
class MessageDigestPasswordEncoder extends BasePasswordEncoder
{
/**
* Constructor.
*
* #param string $algorithm The digest algorithm to use
* #param Boolean $encodeHashAsBase64 Whether to base64 encode the password hash
* #param integer $iterations The number of iterations to use to stretch the password hash
*/
public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $iterations = 5000)
{
$this->algorithm = $algorithm;
$this->encodeHashAsBase64 = $encodeHashAsBase64;
$this->iterations = $iterations;
}
public function encodePassword($raw, $salt)
{
if (!in_array($this->algorithm, hash_algos(), true)) {
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
$salted = $this->mergePasswordAndSalt($raw, $salt);
$digest = hash($this->algorithm, $salted, true);
// "stretch" hash
for ($i = 1; $i < $this->iterations; $i++) {
$digest = hash($this->algorithm, $digest.$salted, true);
}
return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
}
public function isPasswordValid($encoded, $raw, $salt)
{
return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
}
protected function mergePasswordAndSalt($password, $salt)
{
if (empty($salt)) {
return $password;
}
if (false !== strrpos($salt, '{') || false !== strrpos($salt, '}')) {
throw new \InvalidArgumentException('Cannot use { or } in salt.');
}
return $password.'{'.$salt.'}';
}
As you can see, one immediate problem is that hashing is repeated 5000 times by default. This (as well as the other inputs can all be adjusted in you app/config/security.yml file).
You can also see where the salt and password get merged together. Which explains the other stackoverflow answer.
It would be trivial to make a symfony command to just run this encoding algorithm from the symfony console for testing. After that is just a question of adjusting the inputs or tweaking your C code until the results match.
If you are lucky then all your will have to do is add the iteration loop.

How to extract the Signer Info from the Authenticode of a digitally signed PE File encoded using ASN1?

I need to extract the SignerInfo from the Authenticode of a digitally signed PE File in ASN1 structure.
INFO: A PE File contains the authenticode at the offset specified by Security Directory RVA inside Optional Header Data Directories.
I have tried to start after reading the document available at Microsoft Authenticode PE Signature Format but no luck as I am very new to SSL/TSL.
My Question:
Is there a way to parse through the binaries and print the data structure in C String Format?
Is there any way in which I can parse through the given binaries and point to the SignerInfo or SignerName ?
NOTE: I do not want to use any platform dependent APIs as I want the code to be platform-independent.
Thanks in Advance to all Gurus :-)
UPDATE: I found a code in C#. Would anybody help me to find the C equivalent of the same.
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography.X509Certificates;
public class CertInfo
{
public static void Main(String[] args)
{
byte[] certBytes;
X509Certificate x509cert;
while (true)
{
Console.WriteLine("\nEnter File Name: ");
String filename = Console.ReadLine();
if (filename == "") //exit while(true) loop
break;
if (!File.Exists(filename))
{
Console.WriteLine("File \"{0}\" does not exist!\n", filename);
continue;
}
try
{ //try binary DER format first
x509cert = X509Certificate.CreateFromCertFile(filename);
showCertInfo(x509cert);
}
catch (System.Security.Cryptography.CryptographicException cryptder)
{ //not binary DER
StreamReader sr = File.OpenText(filename);
String filestr = sr.ReadToEnd();
sr.Close();
StringBuilder sb = new StringBuilder(filestr);
sb.Replace("-----BEGIN CERTIFICATE-----", "");
sb.Replace("-----END CERTIFICATE-----", "");
//Decode
try
{ //see if the file is a valid Base64 encoded cert
certBytes = Convert.FromBase64String(sb.ToString());
x509cert = new X509Certificate(certBytes);
showCertInfo(x509cert);
}
catch (System.FormatException formexc)
{
Console.WriteLine("Not valid binary DER or Base64 X509 certificate format");
}
catch (System.Security.Cryptography.CryptographicException cryptb64)
{
Console.WriteLine("Not valid binary DER or Base64 X509 certificate format");
}
}
} // end while true
}
private static void showCertInfo(X509Certificate x509cert)
{
Console.WriteLine("Name: " + x509cert.GetName());
Console.WriteLine("Issuer: " + x509cert.GetIssuerName());
Console.WriteLine("Serial Number: " + x509cert.GetSerialNumberString());
Console.WriteLine("Expiration Date: " + x509cert.GetExpirationDateString());
Console.WriteLine("PublicKey: " + x509cert.GetPublicKeyString());
}
}

Resources