signature: Create a helper to verify the signature on files in memory

Signed-off-by: Otavio Pontes <otavio.pontes@intel.com>
This commit is contained in:
Otavio Pontes
2019-08-29 16:08:14 -07:00
committed by Castulo J. Martinez
parent 8cdccdb8f7
commit 65a5fb8276
2 changed files with 105 additions and 68 deletions
+89 -68
View File
@@ -148,50 +148,21 @@ void signature_deinit(void)
CRYPTO_cleanup_all_ex_data();
}
/* Verifies that the file and the signature exists, and does a signature check
* afterwards. If any error is to be considered a verify failure, then
* print_errors should be set to true.
*
* returns: true if able to validate the signature, false otherwise */
bool signature_verify(const char *file, const char *sig_file, bool print_errors)
bool signature_verify_data(const unsigned char *data, size_t data_len, const unsigned char *sig_data, size_t sig_data_len, bool print_errors)
{
int ret;
bool result = false;
struct stat st;
char *errorstr = NULL;
int ret;
int data_fd = -1;
size_t data_len;
unsigned char *data = NULL;
BIO *data_BIO = NULL;
int sig_fd = -1;
size_t sig_len;
unsigned char *sig = NULL;
BIO *sig_BIO = NULL;
PKCS7 *p7 = NULL;
BIO *data_BIO = NULL;
BIO *verify_BIO = NULL;
char *errorstr = NULL;
PKCS7 *p7 = NULL;
/* get the signature */
sig_fd = open(sig_file, O_RDONLY);
if (sig_fd == -1) {
string_or_die(&errorstr, "Failed open %s: %s\n", sig_file, strerror(errno));
goto error;
}
if (fstat(sig_fd, &st) != 0) {
string_or_die(&errorstr, "Failed to stat %s file\n", sig_file);
goto error;
}
sig_len = st.st_size;
sig = mmap(NULL, sig_len, PROT_READ, MAP_PRIVATE, sig_fd, 0);
if (sig == MAP_FAILED) {
string_or_die(&errorstr, "Failed to mmap %s signature\n", sig_file);
goto error;
}
sig_BIO = BIO_new_mem_buf(sig, sig_len);
sig_BIO = BIO_new_mem_buf(sig_data, sig_data_len);
if (!sig_BIO) {
string_or_die(&errorstr, "Failed to read %s signature into BIO\n", sig_file);
string_or_die(&errorstr, "Unable to load signature data into BIO\n");
goto error;
}
@@ -202,26 +173,9 @@ bool signature_verify(const char *file, const char *sig_file, bool print_errors)
goto error;
}
/* get the data to be verified */
data_fd = open(file, O_RDONLY);
if (data_fd == -1) {
string_or_die(&errorstr, "Failed open %s\n", file);
goto error;
}
if (fstat(data_fd, &st) != 0) {
string_or_die(&errorstr, "Failed to stat %s\n", file);
goto error;
}
data_len = st.st_size;
data = mmap(NULL, data_len, PROT_READ, MAP_PRIVATE, data_fd, 0);
if (data == MAP_FAILED) {
string_or_die(&errorstr, "Failed to mmap %s\n", file);
goto error;
}
data_BIO = BIO_new_mem_buf(data, data_len);
if (!data_BIO) {
string_or_die(&errorstr, "Failed to read %s into BIO\n", file);
string_or_die(&errorstr, "Unable to load data into BIO\n");
goto error;
}
@@ -240,6 +194,86 @@ bool signature_verify(const char *file, const char *sig_file, bool print_errors)
string_or_die(&errorstr, "Signature check failed!\n");
}
error:
if (!result && print_errors) {
error("Signature check error\n%s", errorstr);
ERR_print_errors_fp(stderr);
}
free_string(&errorstr);
if (sig_BIO) {
BIO_free(sig_BIO);
}
if (data_BIO) {
BIO_free(data_BIO);
}
if (verify_BIO) {
BIO_free(verify_BIO);
}
if (p7) {
PKCS7_free(p7);
}
return result;
}
/* Verifies that the file and the signature exists, and does a signature check
* afterwards. If any error is to be considered a verify failure, then
* print_errors should be set to true.
*
* returns: true if able to validate the signature, false otherwise */
bool signature_verify(const char *file, const char *sig_file, bool print_errors)
{
struct stat st;
char *errorstr = NULL;
bool result = false;
int data_fd = -1;
size_t data_len;
unsigned char *data = NULL;
int sig_fd = -1;
size_t sig_len;
unsigned char *sig = NULL;
/* get the signature */
sig_fd = open(sig_file, O_RDONLY);
if (sig_fd == -1) {
string_or_die(&errorstr, "Failed open %s: %s\n", sig_file, strerror(errno));
goto error;
}
if (fstat(sig_fd, &st) != 0) {
string_or_die(&errorstr, "Failed to stat %s file\n", sig_file);
goto error;
}
sig_len = st.st_size;
sig = mmap(NULL, sig_len, PROT_READ, MAP_PRIVATE, sig_fd, 0);
if (sig == MAP_FAILED) {
string_or_die(&errorstr, "Failed to mmap %s signature\n", sig_file);
goto error;
}
/* get the data to be verified */
data_fd = open(file, O_RDONLY);
if (data_fd == -1) {
string_or_die(&errorstr, "Failed open %s\n", file);
goto error;
}
if (fstat(data_fd, &st) != 0) {
string_or_die(&errorstr, "Failed to stat %s\n", file);
goto error;
}
data_len = st.st_size;
data = mmap(NULL, data_len, PROT_READ, MAP_PRIVATE, data_fd, 0);
if (data == MAP_FAILED) {
string_or_die(&errorstr, "Failed to mmap %s\n", file);
goto error;
}
result = signature_verify_data(data, data_len, sig, sig_len, print_errors);
error:
if (!result && print_errors) {
error("Signature check error\n%s", errorstr);
@@ -260,19 +294,6 @@ error:
if (data_fd >= 0) {
close(data_fd);
}
if (sig_BIO) {
BIO_free(sig_BIO);
}
if (data_BIO) {
BIO_free(data_BIO);
}
if (verify_BIO) {
BIO_free(verify_BIO);
}
if (p7) {
PKCS7_free(p7);
}
return result;
}
+16
View File
@@ -41,6 +41,22 @@ void signature_deinit(void);
*/
bool signature_verify(const char *file, const char *sig_file, bool print_errors);
/**
* Verify signature of a file in memory.
*
* Works like signature_verify(), but instead of pointing to file names
* in disk, the content of the files should be in memory.
*
* @param data Data to be verified
* @param data_len Length of data in bytes
* @param sig Data to be verified
* @param sig_len Length of data in bytes
* @param print_errors if false, errors aren't printed.
*
* @return true if the file is signed with certificate used signature_init()
*/
bool signature_verify_data(const unsigned char *data, size_t data_len, const unsigned char *sig_data, size_t sig_data_len, bool print_errors);
#ifdef __cplusplus
}
#endif