207 lines
6.5 KiB
C
207 lines
6.5 KiB
C
#include "certificate.h"
|
|
#include "audit/audit.h"
|
|
#include "audit/file.h"
|
|
|
|
|
|
int certificate(char **argv, const int argc){
|
|
int res;
|
|
int is_pubkey = 0;
|
|
int to_stdout = 0;
|
|
char buf_pkey[BUF_PATH_PKEY];
|
|
struct stat st_stat;
|
|
int fd;
|
|
off_t len;
|
|
int type; /* Indicate the type of file: RSA, x509 */
|
|
|
|
/* struct st_audit for permission */
|
|
struct st_audit st_audit_owner = {0};
|
|
struct st_audit st_audit_group = {0};
|
|
struct st_audit st_audit_other = {0};
|
|
|
|
/* struct audit_fips for the FIPS audit */
|
|
struct audit_fips st_audit_fips = {0};
|
|
|
|
/* struct for keyinformation */
|
|
struct keyinfo st_keyinfo = {0};
|
|
|
|
// TODO: need to review how to parse args
|
|
res = check_arguments_certificate(argv, argc, buf_pkey, &type, &is_pubkey, &to_stdout);
|
|
|
|
if (res == -1)
|
|
return -1;
|
|
|
|
if (type <= 0)
|
|
return -1;
|
|
|
|
// Check if public key file exist
|
|
if (file_exist(buf_pkey) == -1){
|
|
printf("The file %s doesn't exist\n", buf_pkey);
|
|
return -1;
|
|
}
|
|
|
|
// Check if public key file exist
|
|
if (file_exist(buf_pkey) == -1){
|
|
printf("The file %s doesn't exist\n", buf_pkey);
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Print the filename,
|
|
* Owner of the file
|
|
* Size of the file
|
|
* And other information
|
|
*/
|
|
if ((fd = open(buf_pkey, O_RDONLY)) < 0){
|
|
printf("Failed to open the file\n");
|
|
}
|
|
fstat(fd, &st_stat);
|
|
|
|
printf("File information\n");
|
|
printf("\tFilename: %s\n", buf_pkey);
|
|
printf("\tFile size: %ld\n", st_stat.st_size);
|
|
printf("\tPermission: %d\n", convert_mode_t(st_stat.st_mode));
|
|
|
|
/*
|
|
* Check certificate's file
|
|
* - owner of the certificate
|
|
* - permission of the file
|
|
*/
|
|
printf("\nChecking file ownerships compliance...\n");
|
|
|
|
uid_t uid = st_stat.st_uid;
|
|
char username[64];
|
|
struct st_audit audit_ownshp = ownership(uid, username, 64);
|
|
printf("%s\n", audit_ownshp.result);
|
|
|
|
/*
|
|
* Checking permission file
|
|
* For a better security, only the owner can have the privilege to read/write the certificate
|
|
*/
|
|
printf("\nChecking file permissions compliance...\n");
|
|
permission(st_stat.st_mode, &st_audit_owner, &st_audit_group, &st_audit_other);
|
|
printf("%s\n", st_audit_owner.result);
|
|
if (st_audit_group.audit == FALSE)
|
|
printf("%s\n", st_audit_group.result);
|
|
if (st_audit_other.audit == FALSE)
|
|
printf("%s\n", st_audit_other.result);
|
|
|
|
/*************************/
|
|
/* Check FIPS compliance */
|
|
/*************************/
|
|
printf("\nChecking FIPS compliance...\n");
|
|
|
|
res = fips(buf_pkey, &st_audit_fips, &st_keyinfo, type, is_pubkey);
|
|
if (res > 0){
|
|
printf("Error during check FIPS compliance\n");
|
|
return -1;
|
|
}
|
|
|
|
/* Print information regarding the key */
|
|
printf("Certificate information:\n");
|
|
if (st_keyinfo.algo == ALGO_RSA){
|
|
printf("\tKey size: %d bytes (%d)\n", st_keyinfo.st_rsa.keysize, (st_keyinfo.st_rsa.keysize * 8));
|
|
printf("\tExponent: %lu\n", st_keyinfo.st_rsa.exponent);
|
|
printf("\tAlgorithm: RSA\n");
|
|
if (st_keyinfo.st_rsa.format == RSA_FORMAT_PKCS1)
|
|
printf("\tFormat RSA key: PKCS#1\n");
|
|
if (st_keyinfo.st_rsa.format == RSA_FORMAT_SPKI)
|
|
printf("\tFormat RSA key: SPKI (PEM)\n");
|
|
|
|
/* Print the audit result */
|
|
printf("\nExponent result:\n");
|
|
printf("\t%s\n", st_audit_fips.audit_rsa.audit_exponent.result);
|
|
printf("Keysize result:\n");
|
|
printf("\t%s\n", st_audit_fips.audit_rsa.audit_keysize.result);
|
|
}
|
|
if (st_keyinfo.algo == ALGO_EC) {
|
|
printf("\tAlgorithm: Elliptic Curve\n");
|
|
printf("\tCurve name: %s\n", st_keyinfo.s_ecc.curve);
|
|
printf("\tCofactor: %s\n", st_keyinfo.s_ecc.cofactor);
|
|
printf("\tOrder: %s\n", st_keyinfo.s_ecc.order);
|
|
printf("\tOrder length: %d\n", st_keyinfo.s_ecc.order_bits);
|
|
printf("\tGenerator: %s\n", st_keyinfo.s_ecc.g);
|
|
|
|
/* Should I allocate each variables in audit/fips.c and clean it ? */
|
|
|
|
OPENSSL_free(st_keyinfo.s_ecc.cofactor);
|
|
/* It's a const char *, I cannot free it */
|
|
//OPENSSL_free(st_keyinfo.s_ecc.curve);
|
|
OPENSSL_free(st_keyinfo.s_ecc.order);
|
|
OPENSSL_free(st_keyinfo.s_ecc.g);
|
|
EC_KEY_free(st_keyinfo.s_ecc.ec);
|
|
st_keyinfo.s_ecc.ec = NULL;
|
|
|
|
/* Print the audit result */
|
|
printf("\nCurve result: \n");
|
|
printf("\t%s\n", st_audit_fips.audit_ecc.audit_curve.result);
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
|
|
printf("\n");
|
|
|
|
/* If we dump the key, we read it */
|
|
if (to_stdout){
|
|
int len = 0;
|
|
|
|
st_keyinfo.st_rsa.key = (char *)malloc(st_stat.st_size + 1);
|
|
lseek(fd, 0, SEEK_SET);
|
|
len = read(fd, st_keyinfo.st_rsa.key, st_stat.st_size);
|
|
st_keyinfo.st_rsa.key[len] = '\0';
|
|
|
|
printf("Dump the key:\n%s\n", st_keyinfo.st_rsa.key);
|
|
|
|
free(st_keyinfo.st_rsa.key);
|
|
}
|
|
|
|
close(fd);
|
|
}
|
|
/*
|
|
* This function check arguments passed for executing the program. For the certificate module, the type argument is mandatory, which indicate the type of key (RSA or x509).
|
|
Also, the argument -privin or -pubin is mandatory. One is for the private key followed by the pathname and the second one is the public key.
|
|
*/
|
|
static int check_arguments_certificate(char **argv, const int argc, char *buf_pkey, int *type, int *is_pubkey, int *to_stdout){
|
|
int res = -1;
|
|
/* we bypass the first action arguments */
|
|
for (int i = 3; i < argc; i++){
|
|
/*if(argv[i][0] == '-'){}*/
|
|
size_t l = strlen(argv[i]);
|
|
if (strncmp(argv[i], "-type", l) == 0){
|
|
if (strcmp(argv[i + 1], "rsa") == 0)
|
|
*type = TYPE_RSA;
|
|
else if (strcmp(argv[i + 1], "elliptic") == 0)
|
|
*type = TYPE_ELLIPTIC;
|
|
else if (strcmp(argv[i + 1], "x509") == 0)
|
|
*type = TYPE_X509;
|
|
else
|
|
res = -1;
|
|
}
|
|
if (strncmp(argv[i], "-pubin", l) == 0){
|
|
//printf("%s\n", argv[i + 1]);
|
|
strncpy(buf_pkey, argv[i + 1], BUF_PATH_PKEY);
|
|
res = 0;
|
|
*is_pubkey = 1;
|
|
}
|
|
if (strncmp(argv[i], "-privin", l) == 0){
|
|
strncpy(buf_pkey, argv[i + 1], BUF_PATH_PKEY);
|
|
res = 0;
|
|
*is_pubkey = 0;
|
|
}
|
|
if (strncmp(argv[i], "-text", l) == 0)
|
|
*to_stdout = 1;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
/*
|
|
* This function check if the file exist
|
|
* If yes, return 0, otherwise return-1
|
|
*/
|
|
static int file_exist(const char *file){
|
|
if (access(file, F_OK) == 0)
|
|
return 0;
|
|
return -1;
|
|
}
|
|
|