/*
* Only suitable for PEM format certificate file, and not apply
* for DER certificate file.
*
* */
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
int default_days = 9;
static int
get_cert_time(char *cert, char *date_buf, int date_buf_len)
{
BIO *b;
X509 *x509cert;
ASN1_TIME *get_date; //save valid time
if (cert == NULL) {
printf("[%s: %d] Certificate file(\"%s\") is NULL!\n",
__FUNCTION__, __LINE__, cert);
return -1;
}
/* Only suitable for PEM format digital certificate file. */
b = BIO_new_file(cert, "r");
if (b == NULL) {
printf("[%s: %d] bio is NULL!\n", __FUNCTION__, __LINE__);
return -1;
}
x509cert = PEM_read_bio_X509(b, NULL, NULL, NULL);
if (x509cert == NULL) {
printf("[%s: %d] read bio failed!\n", __FUNCTION__, __LINE__);
return -1;
}
get_date = X509_get_notBefore(x509cert);
printf("Not Before: %s\n", get_date->data);
//get_date = X509_get_notAfter(x509cert);
//printf("Not After: %s\n", get_date->data);
if (get_date->length > date_buf_len) {
printf("[%s: %d] date length too long!\n",
__FUNCTION__, __LINE__);
return -1;
}
strncpy(date_buf, (char *)get_date->data, date_buf_len);
X509_free(x509cert);
return 0;
}
static int
update_cert_process(time_t current_time, char *cert_date)
{
time_t update_time = 0;
struct tm *gmt;
char *date_buf = NULL;
char *date_buf2 = NULL;
int result = -1;
update_time = current_time - default_days * 24 * 60 * 60;
printf("Before %d day: %ld\n", default_days, (long)update_time);
gmt = gmtime(&update_time);
date_buf = (char *)malloc(15 * sizeof(char) + 1);
if (date_buf == NULL) {
printf("[%s:%d] malloc failed!\n", __FUNCTION__, __LINE__);
return -1;
}
/* Print current date. */
snprintf(date_buf, 16,"%04d%02d%02d%02d%02d%02dZ", gmt->tm_year + 1900, gmt->tm_mon+1,
gmt->tm_mday, gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
date_buf[15] = '\0';
printf("Before %d days: %s\n", default_days, date_buf);
/* Truncate "20", for example "2017", "17" is leaved. */
date_buf2 = (char *)malloc(15 * sizeof(char) + 1);
if (date_buf2 == NULL) {
printf("[%s:%d] malloc failed!\n", __FUNCTION__, __LINE__);
return -1;
}
strncpy(date_buf2, date_buf + 2, 16);
printf("date_buf2: %s\n", date_buf2);
result = strncmp(date_buf2, cert_date, strlen(cert_date));
printf("date_buf2: %s,\ncert_date: %s,\nresult: %d\n",
date_buf2, cert_date, result);
/* 3. Judge whether to update the certificate file. */
if (result > 0) {
printf("It's time to updte the certificate file!\n");
} else {
printf("Don't update the certificate file!\n");
}
free(date_buf);
free(date_buf2);
return 0;
}
int
main(int argc, char *const argv[])
{
time_t t;
struct tm *gmt;
char *date_buf = NULL;
char *date_buf2 = NULL;
char *cert_date = NULL;
int cert_date_len = -1;
int update_result = -1;
/* 1. Obtain certificate file date. */
cert_date_len = 13; /* Not Before: 171228063543Z.*/
cert_date = (char *)malloc(cert_date_len * sizeof(char) + 1);
if (get_cert_time(argv[1], cert_date, cert_date_len + 1) == -1) {
printf("[%s: %d]: Obtain certificate date failed!\n",
__FUNCTION__, __LINE__);
return -1;
}
printf("certficate date: %s\n", cert_date);
/* 2. Obtain current date. */
t = time(NULL);
printf("Current time: %ld\n", (long)t);
gmt = gmtime(&t);
date_buf = (char *)malloc(15 * sizeof(char) + 1);
if (date_buf == NULL) {
printf("[%s:%d] malloc failed!\n", __FUNCTION__, __LINE__);
return -1;
}
/* Print current date. */
snprintf(date_buf, 16,"%04d%02d%02d%02d%02d%02dZ", gmt->tm_year + 1900, gmt->tm_mon+1,
gmt->tm_mday, gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
date_buf[15] = '\0';
printf("Current date: %s\n", date_buf);
/* Truncate "20", for example "2017", "17" is leaved. */
date_buf2 = (char *)malloc(15 * sizeof(char) + 1);
if (date_buf2 == NULL) {
printf("[%s:%d] malloc failed!\n", __FUNCTION__, __LINE__);
return -1;
}
strncpy(date_buf2, date_buf + 2, 15);
printf("date_buf2: %s\n", date_buf2);
update_result = strncmp(date_buf2, cert_date, strlen(cert_date));
printf("date_buf2: %s,\ncert_date: %s,\nresult: %d\n",
date_buf2, cert_date, update_result);
/* 3. Judge whether to update the certificate file. */
if (update_result > 0) {
printf("The certificate file is valid!\n");
if (update_cert_process(t, cert_date) == -1) {
printf("[%s : %d] Update certificate failed!\n",
__FUNCTION__, __LINE__);
} else {
printf("Update certificate successfully!\n");
}
} else {
printf("The certificate file is invalid!\n");
}
free(date_buf);
free(date_buf2);
free(cert_date);
printf("GMT is: %s", asctime(gmt));
return 0;
}
Makefile:
prefix=
CC=$(prefix)gcc
INCLUDE= -I./sdk/include
CFLAGS= -Wall -g
LDFLAGS= -L./sdk/lib/x86_64 -lssl -lcrypto -ldl
default: binary modules
binary: objs/get_certificate_date.bin
objs/get_certificate_date.bin: objs/src/get_certificate_date.o
$(CC) -o $@ $^ $(LDFLAGS)
modules:
objs/src/get_certificate_date.o: ./get_certificate_date.c
$(CC) -c $(CFLAGS) $(INCLUDE) \
-o $@ $^
clean:
rm -rf objs/*.bin objs/src/*.o
Result:
$ ./objs/get_certificate_date.bin client.crt
Not Before: 171228063543Z
certficate date: 171228063543Z
Current time: 1515399527
Current date: 20180108081847Z
date_buf2: 180108081847Z
date_buf2: 180108081847Z,
cert_date: 171228063543Z,
result: 1
The certificate file is valid!
Before 9 day: 1514621927
Before 9 days: 20171230081847Z
date_buf2: 171230081847Z
date_buf2: 171230081847Z,
cert_date: 171228063543Z,
result: 1
It's time to updte the certificate file!
Update certificate successfully!
GMT is: Sat Dec 30 08:18:47 2017