修改实体证书检测

This commit is contained in:
fengweihao
2019-08-28 11:42:09 +08:00
parent 9cf2e7be8f
commit 4b55add64d

View File

@@ -4,7 +4,7 @@
> Mail:
> Created Time: Fri 01 Jun 2018 02:00:56 AM PDT
************************************************************************/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -43,6 +43,7 @@ enum x509_input_file{
INPUT_FILE_CRL,
INPUT_FILE_LIST,
INPUT_FILE_CHECK,
INPUT_FILE_HOST,
INPUT_FILE_CHAIN,
};
@@ -64,11 +65,12 @@ static void help()
printf("Welcome to x509 %s\n", "1.1.1");
printf("x509 <-incert |-inkey | -incrl | -inlist> arg\n"
"Usage:\n"
" -incert | input certificate file [url]\n"
" -incert | input certificate file\n"
" -inkey | input private key file\n"
" -incrl | input certificate revocation list\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)
@@ -267,7 +269,7 @@ int x509_get_ValidDate(X509 *x509)
BIO_free_all(STDout);
return 0;
}
#if 0
static char*
x509_get_alt_name(X509 *x509)
{
@@ -279,11 +281,13 @@ x509_get_alt_name(X509 *x509)
if (cnt < 0)
goto finish;
int gnnamelen = cnt * 64;
gnname = (char *)malloc(2048);
gnname = (char *)malloc(gnnamelen);
if (!gnname)
goto finish;
memset(gnname, 0, 2048);
memset(gnname, 0, gnnamelen);
for (i = 0; i < cnt; i++)
{
@@ -291,18 +295,15 @@ x509_get_alt_name(X509 *x509)
ASN1_STRING *uri = GENERAL_NAME_get0_value(generalName, &gtype);
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)
continue;
if (size >= 2048)
break;
}
}
finish:
return gnname;
}
#endif
void x509_get_name(X509_NAME *name, int obase)
{
@@ -511,7 +512,7 @@ int X509_check_valid_date(X509 *x509)
return 0;
}
int x509_parse_cert(char *certfile, char *input_url)
int x509_parse_cert(char *certfile, char *host)
{
int xret = -1;
int informat = 0;
@@ -525,24 +526,7 @@ int x509_parse_cert(char *certfile, char *input_url)
}
printf("Successful certificate conversion\n");
printf("Ca Format : %s\n", val_to_str(informat, format_vals));
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);
printf("Ca Constraints : %s\n", (x509_get_ExtBasicConstraints(x509) != NULL)?x509_get_ExtBasicConstraints(x509): "NULL");
if (informat == LOCAL_USER_P12 || informat == LOCAL_USER_PEN){
if (stack_ca){
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 : ");
x509_get_name(X509_get_subject_name(x509), 16);
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));
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;
finish:
@@ -683,7 +677,6 @@ x509_parse_cert_list(char *certlist)
perror(certlist);
goto err;
}
printf("Certificate List:\n");
for (;;) {
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;
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;
help:
@@ -792,6 +793,178 @@ finish:
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 iformat = -1;
@@ -817,6 +990,9 @@ int x509_check_format(int argc, char **argv)
case INPUT_FILE_CHECK:
x509_parse_check(infile, infile2);
break;
case INPUT_FILE_HOST:
x509_check_host(infile, infile2);
break;
default:
goto help;
}