CryptoDit/certificate.c
2026-01-31 16:45:53 +01:00

188 lines
5.6 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");
/*if (type == TYPE_X509){
printf("Cannot decrypt x509 certifcate, it is not implemented yet\n");
return 0;
}*/
res = fips(buf_pkey, &st_audit_fips, &st_keyinfo, type, is_pubkey, to_stdout);
if (res < 0){
printf("Error during check FIPS compliance\n");
return -1;
}
/* Print information regarding the key */
printf("Certificate information:\n");
printf("\tKey size: %d bytes (%d)\n", st_keyinfo.keysize, (st_keyinfo.keysize * 8));
printf("\tExponent: %lu\n", st_keyinfo.exponent);
if (st_keyinfo.algo == ALGO_RSA)
printf("\tAlgorithm: RSA\n");
if (st_keyinfo.algo == ALGO_EC)
printf("\tAlgorithm: Elliptic Curve\n");
if (st_keyinfo.format == RSA_FORMAT_PKCS1)
printf("\tFormat RSA key: PKCS#1\n");
if (st_keyinfo.format == RSA_FORMAT_SPKI)
printf("\tFormat RSA key: SPKI\n");
printf("\n");
/* Print the audit result */
printf("Exponent result:\n");
printf("\t%s\n", st_audit_fips.audit_exponent.result);
printf("Keysize result:\n");
printf("\t%s\n", st_audit_fips.audit_keysize.result);
printf("\n");
/* If we dump the key, we read it */
if (to_stdout){
int len = 0;
st_keyinfo.key = (char *)malloc(st_stat.st_size + 1);
lseek(fd, 0, SEEK_SET);
len = read(fd, st_keyinfo.key, st_stat.st_size);
st_keyinfo.key[len] = '\0';
printf("Dump the key:\n%s\n", st_keyinfo.key);
free(st_keyinfo.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], "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;
}