修改实体证书检测
This commit is contained in:
240
src/x509.c
240
src/x509.c
@@ -4,7 +4,7 @@
|
|||||||
> Mail:
|
> Mail:
|
||||||
> Created Time: Fri 01 Jun 2018 02:00:56 AM PDT
|
> Created Time: Fri 01 Jun 2018 02:00:56 AM PDT
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -43,6 +43,7 @@ enum x509_input_file{
|
|||||||
INPUT_FILE_CRL,
|
INPUT_FILE_CRL,
|
||||||
INPUT_FILE_LIST,
|
INPUT_FILE_LIST,
|
||||||
INPUT_FILE_CHECK,
|
INPUT_FILE_CHECK,
|
||||||
|
INPUT_FILE_HOST,
|
||||||
INPUT_FILE_CHAIN,
|
INPUT_FILE_CHAIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,11 +65,12 @@ static void help()
|
|||||||
printf("Welcome to x509 %s\n", "1.1.1");
|
printf("Welcome to x509 %s\n", "1.1.1");
|
||||||
printf("x509 <-incert |-inkey | -incrl | -inlist> arg\n"
|
printf("x509 <-incert |-inkey | -incrl | -inlist> arg\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
" -incert | input certificate file [url]\n"
|
" -incert | input certificate file\n"
|
||||||
" -inkey | input private key file\n"
|
" -inkey | input private key file\n"
|
||||||
" -incrl | input certificate revocation list\n"
|
" -incrl | input certificate revocation list\n"
|
||||||
" -inlist | input certificate list file,format = pem\n"
|
" -inlist | input certificate list file,format = pem\n"
|
||||||
" -incheck | input certificate file and intpu key file\n");
|
" -incheck | input certificate file and intpu key file\n"
|
||||||
|
" -inhost | input san file and intpu fqdn file\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static X509* base_load_pkcs12(BIO *in, EVP_PKEY **pkey, X509 **x, STACK_OF(X509) **ca)
|
static X509* base_load_pkcs12(BIO *in, EVP_PKEY **pkey, X509 **x, STACK_OF(X509) **ca)
|
||||||
@@ -267,7 +269,7 @@ int x509_get_ValidDate(X509 *x509)
|
|||||||
BIO_free_all(STDout);
|
BIO_free_all(STDout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
static char*
|
static char*
|
||||||
x509_get_alt_name(X509 *x509)
|
x509_get_alt_name(X509 *x509)
|
||||||
{
|
{
|
||||||
@@ -279,11 +281,13 @@ x509_get_alt_name(X509 *x509)
|
|||||||
|
|
||||||
if (cnt < 0)
|
if (cnt < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
|
int gnnamelen = cnt * 64;
|
||||||
|
|
||||||
gnname = (char *)malloc(2048);
|
gnname = (char *)malloc(gnnamelen);
|
||||||
if (!gnname)
|
if (!gnname)
|
||||||
goto finish;
|
goto finish;
|
||||||
memset(gnname, 0, 2048);
|
memset(gnname, 0, gnnamelen);
|
||||||
|
|
||||||
for (i = 0; i < cnt; i++)
|
for (i = 0; i < cnt; i++)
|
||||||
{
|
{
|
||||||
@@ -291,18 +295,15 @@ x509_get_alt_name(X509 *x509)
|
|||||||
ASN1_STRING *uri = GENERAL_NAME_get0_value(generalName, >ype);
|
ASN1_STRING *uri = GENERAL_NAME_get0_value(generalName, >ype);
|
||||||
if (gtype == GEN_DNS)
|
if (gtype == GEN_DNS)
|
||||||
{
|
{
|
||||||
size += snprintf(gnname + size, 2048, "%s, ", ASN1_STRING_data(uri));
|
size += snprintf(gnname + size, gnnamelen, "%s;", ASN1_STRING_data(uri));
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
continue;
|
continue;
|
||||||
if (size >= 2048)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
return gnname;
|
return gnname;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void x509_get_name(X509_NAME *name, int obase)
|
void x509_get_name(X509_NAME *name, int obase)
|
||||||
{
|
{
|
||||||
@@ -511,7 +512,7 @@ int X509_check_valid_date(X509 *x509)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x509_parse_cert(char *certfile, char *input_url)
|
int x509_parse_cert(char *certfile, char *host)
|
||||||
{
|
{
|
||||||
int xret = -1;
|
int xret = -1;
|
||||||
int informat = 0;
|
int informat = 0;
|
||||||
@@ -525,24 +526,7 @@ int x509_parse_cert(char *certfile, char *input_url)
|
|||||||
}
|
}
|
||||||
printf("Successful certificate conversion\n");
|
printf("Successful certificate conversion\n");
|
||||||
printf("Ca Format : %s\n", val_to_str(informat, format_vals));
|
printf("Ca Format : %s\n", val_to_str(informat, format_vals));
|
||||||
|
printf("Ca Constraints : %s\n", (x509_get_ExtBasicConstraints(x509) != NULL)?x509_get_ExtBasicConstraints(x509): "NULL");
|
||||||
char *constraints = NULL;
|
|
||||||
constraints = x509_get_ExtBasicConstraints(x509);
|
|
||||||
printf("Ca Constraints : %s\n", (constraints != NULL)?constraints: "NULL");
|
|
||||||
/*end-entity certificate san**/
|
|
||||||
if ((constraints != NULL && STRSTR(constraints, "End Entity")) ||
|
|
||||||
constraints == NULL)
|
|
||||||
{
|
|
||||||
char *cn = x509_get_cn(x509);
|
|
||||||
if (!cn || X509_check_host(x509, cn, strlen(cn), 0, NULL) != 1 ||
|
|
||||||
input_url == NULL || X509_check_host(x509, input_url, strlen(input_url), 0, NULL) != 1)
|
|
||||||
{
|
|
||||||
printf("Match host name: %s\n", "Matching failure");
|
|
||||||
}
|
|
||||||
kfree(cn);
|
|
||||||
}
|
|
||||||
printf("Match host name: %s\n", "Successful matching");
|
|
||||||
if (constraints) kfree(constraints);
|
|
||||||
if (informat == LOCAL_USER_P12 || informat == LOCAL_USER_PEN){
|
if (informat == LOCAL_USER_P12 || informat == LOCAL_USER_PEN){
|
||||||
if (stack_ca){
|
if (stack_ca){
|
||||||
printf("Chain Length : %d\n", sk_X509_num(stack_ca) + 1);
|
printf("Chain Length : %d\n", sk_X509_num(stack_ca) + 1);
|
||||||
@@ -559,11 +543,21 @@ int x509_parse_cert(char *certfile, char *input_url)
|
|||||||
printf("Ca SubjectName : ");
|
printf("Ca SubjectName : ");
|
||||||
x509_get_name(X509_get_subject_name(x509), 16);
|
x509_get_name(X509_get_subject_name(x509), 16);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
char *alt_name = x509_get_alt_name(x509);
|
||||||
|
printf("Ca AltName : %s\n", (alt_name != NULL)?alt_name:"NULL");
|
||||||
|
free(alt_name);
|
||||||
printf("Ca Fingerprint : %s\n", x509_get_fingerprint(x509));
|
printf("Ca Fingerprint : %s\n", x509_get_fingerprint(x509));
|
||||||
x509_get_ValidDate(x509);
|
x509_get_ValidDate(x509);
|
||||||
if (X509_check_valid_date(x509) < 0)
|
printf("Ca valid date : %s\n", (X509_check_valid_date(x509) == 0)?"valid":"expire");
|
||||||
|
|
||||||
|
/* self testing***/
|
||||||
|
if (host != NULL)
|
||||||
{
|
{
|
||||||
printf("CA state : ERR_CERT_DATE_INVALID\n");
|
if (X509_check_host(x509, host, strlen(host), 0, NULL) == 1)
|
||||||
|
printf("Match host name: %s\n", "Successful matching");
|
||||||
|
else
|
||||||
|
printf("Match host name: %s\n", "Matching failure");
|
||||||
|
|
||||||
}
|
}
|
||||||
xret = 0;
|
xret = 0;
|
||||||
finish:
|
finish:
|
||||||
@@ -683,7 +677,6 @@ x509_parse_cert_list(char *certlist)
|
|||||||
perror(certlist);
|
perror(certlist);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Certificate List:\n");
|
printf("Certificate List:\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
|
x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
|
||||||
@@ -755,6 +748,14 @@ decoder_argv_parser(int argc, char **argv, char **infile, char **infile2)
|
|||||||
iformat = INPUT_FILE_CHECK;
|
iformat = INPUT_FILE_CHECK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (STRCMP(argv[i], "-inhost") == 0){
|
||||||
|
if (--argc < 1)
|
||||||
|
goto help;
|
||||||
|
*infile = argv[i+1];
|
||||||
|
*infile2 = argv[i+2];
|
||||||
|
iformat = INPUT_FILE_HOST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
goto finish;
|
goto finish;
|
||||||
help:
|
help:
|
||||||
@@ -792,6 +793,178 @@ finish:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static X509 *make_cert()
|
||||||
|
{
|
||||||
|
X509 *x509 = X509_new();
|
||||||
|
if (x509 == NULL)
|
||||||
|
goto out;
|
||||||
|
if (!X509_set_version(x509, 3))
|
||||||
|
goto out;
|
||||||
|
return x509;
|
||||||
|
out:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *execute_read_file(const char *filename)
|
||||||
|
{
|
||||||
|
FILE *file = NULL;
|
||||||
|
long length = 0;
|
||||||
|
char *content = NULL;
|
||||||
|
size_t read_chars = 0;
|
||||||
|
|
||||||
|
file = fopen(filename, "rb");
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (fseek(file, 0, SEEK_END) != 0)
|
||||||
|
{
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
length = ftell(file);
|
||||||
|
if (length < 0)
|
||||||
|
{
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (fseek(file, 0, SEEK_SET) != 0)
|
||||||
|
{
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate content buffer */
|
||||||
|
content = (char*)malloc((size_t)length + sizeof(""));
|
||||||
|
if (content == NULL)
|
||||||
|
{
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the file into memory */
|
||||||
|
read_chars = fread(content, sizeof(char), (size_t)length, file);
|
||||||
|
if ((long)read_chars != length)
|
||||||
|
{
|
||||||
|
free(content);
|
||||||
|
content = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
content[read_chars] = '\0';
|
||||||
|
cleanup:
|
||||||
|
if (file != NULL)
|
||||||
|
{
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_trim(const char *str)
|
||||||
|
{
|
||||||
|
unsigned int uLen = strlen(str);
|
||||||
|
|
||||||
|
if(0 == uLen){
|
||||||
|
return '\0';
|
||||||
|
}
|
||||||
|
char *strRet = (char *)malloc(uLen + 1);
|
||||||
|
memset(strRet, 0, uLen+1);
|
||||||
|
unsigned int i = 0, j = 0;
|
||||||
|
for(i=0; i<uLen+1; i++)
|
||||||
|
{
|
||||||
|
if(str[i] != ' ')
|
||||||
|
{
|
||||||
|
strRet[j++] = str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strRet[j] = '\0';
|
||||||
|
return strRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_altname(X509 *crt, int type, const char *sanfile)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
GENERAL_NAMES *gens = NULL;
|
||||||
|
GENERAL_NAME *gen = NULL;
|
||||||
|
ASN1_IA5STRING *ia5 = NULL;
|
||||||
|
|
||||||
|
gens = sk_GENERAL_NAME_new_null();
|
||||||
|
if (gens == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
char *buff = execute_read_file(sanfile);
|
||||||
|
if (buff == NULL){
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
char *sanline=NULL, *host = NULL;
|
||||||
|
char seps[] = ";";
|
||||||
|
sanline = strtok(buff, seps);
|
||||||
|
while (sanline)
|
||||||
|
{
|
||||||
|
asprintf(&host, "%s", sanline);
|
||||||
|
gen = GENERAL_NAME_new();
|
||||||
|
if (gen == NULL)
|
||||||
|
goto out;
|
||||||
|
ia5 = ASN1_IA5STRING_new();
|
||||||
|
if (ia5 == NULL)
|
||||||
|
goto out;
|
||||||
|
if (!ASN1_STRING_set(ia5, host, -1))
|
||||||
|
goto out;
|
||||||
|
switch (type) {
|
||||||
|
case GEN_EMAIL:
|
||||||
|
case GEN_DNS:
|
||||||
|
GENERAL_NAME_set0_value(gen, type, ia5);
|
||||||
|
ia5 = NULL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
sk_GENERAL_NAME_push(gens, gen);
|
||||||
|
gen = NULL;
|
||||||
|
free(host);
|
||||||
|
sanline = strtok(NULL, seps);
|
||||||
|
if (sanline == NULL || strlen(sanline) == 1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
|
||||||
|
goto out;
|
||||||
|
ret = 1;
|
||||||
|
out:
|
||||||
|
ASN1_IA5STRING_free(ia5);
|
||||||
|
GENERAL_NAME_free(gen);
|
||||||
|
finish:
|
||||||
|
GENERAL_NAMES_free(gens);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_check_host(const char *sanfile, const char *urlfile)
|
||||||
|
{
|
||||||
|
#define LINE_SIZE (1024)
|
||||||
|
|
||||||
|
FILE *fp = NULL;
|
||||||
|
char line[LINE_SIZE];
|
||||||
|
|
||||||
|
if (sanfile == NULL || urlfile == NULL){
|
||||||
|
goto help;
|
||||||
|
}
|
||||||
|
X509 *x509 = make_cert();
|
||||||
|
if (x509 == NULL)
|
||||||
|
return -1;
|
||||||
|
set_altname(x509, GEN_DNS, sanfile);
|
||||||
|
fp = fopen(urlfile, "r");
|
||||||
|
assert(fp != NULL);
|
||||||
|
while(fgets(line, LINE_SIZE - 1, fp))
|
||||||
|
{
|
||||||
|
if (line[0] == '\0' || X509_check_host(x509, line, strlen(line) -1, 0, NULL) != 1)
|
||||||
|
{
|
||||||
|
printf("Fqdn :%.*s Status: %s\n", (int)(strlen(line)-1), line, "Matching failure");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
goto finish;
|
||||||
|
help:
|
||||||
|
help();
|
||||||
|
finish:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int x509_check_format(int argc, char **argv)
|
int x509_check_format(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int iformat = -1;
|
int iformat = -1;
|
||||||
@@ -817,6 +990,9 @@ int x509_check_format(int argc, char **argv)
|
|||||||
case INPUT_FILE_CHECK:
|
case INPUT_FILE_CHECK:
|
||||||
x509_parse_check(infile, infile2);
|
x509_parse_check(infile, infile2);
|
||||||
break;
|
break;
|
||||||
|
case INPUT_FILE_HOST:
|
||||||
|
x509_check_host(infile, infile2);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto help;
|
goto help;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user