Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4662a114 authored by Szymon Starzycki's avatar Szymon Starzycki Committed by Colin Cross
Browse files

Revert "Revert "Fastbootd: flashing certification""

CMS functionality is now available

This reverts commit 068b71dd.

Conflicts:
	fastbootd/Android.mk
	fastbootd/fastbootd.c
	fastbootd/utils.c
	fastbootd/utils.h

Change-Id: I1a27459b41d9297603deb124c65f237ff971e5b6
parent 27ea99fb
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ LOCAL_SRC_FILES := \
    protocol.c \
    network_discovery.c \
    socket_client.c \
    secure.c \
    transport.c \
    transport_socket.c \
    trigger.c \
@@ -41,7 +42,7 @@ LOCAL_SRC_FILES := \

LOCAL_MODULE := fastbootd
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter
LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter -DFLASH_CERT
LOCAL_LDFLAGS := -ldl

LOCAL_SHARED_LIBRARIES := \
+32 −7
Original line number Diff line number Diff line
@@ -52,6 +52,8 @@

static void cmd_boot(struct protocol_handle *phandle, const char *arg)
{
    int sz, atags_sz, new_atags_sz;
    int rv;
    unsigned kernel_actual;
    unsigned ramdisk_actual;
    unsigned second_actual;
@@ -59,9 +61,11 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg)
    void *ramdisk_ptr;
    void *second_ptr;
    struct boot_img_hdr *hdr;
    int sz, atags_sz, new_atags_sz;
    int rv;
    char *ptr = NULL, *atags_ptr = NULL, *new_atags = NULL;
    char *ptr = NULL;
    char *atags_ptr = NULL;
    char *new_atags = NULL;
    int data_fd = 0;

    D(DEBUG, "cmd_boot %s\n", arg);

    if (phandle->download_fd < 0) {
@@ -75,9 +79,18 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg)
        goto error;
    }

    sz = get_file_size(phandle->download_fd);
    // TODO: With cms we can also verify partition name included as
    // cms signed attribute
    if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) {
        fastboot_fail(phandle, "Access forbiden you need the certificate");
        return;
    }

    sz = get_file_size(data_fd);

    ptr = (char *) mmap(NULL, sz, PROT_READ,
                        MAP_POPULATE | MAP_PRIVATE, phandle->download_fd, 0);
                        MAP_POPULATE | MAP_PRIVATE, data_fd, 0);

    hdr = (struct boot_img_hdr *) ptr;

    if (ptr == MAP_FAILED) {
@@ -130,6 +143,7 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg)
    free(atags_ptr);
    munmap(ptr, sz);
    free(new_atags);
    close(data_fd);

    D(INFO, "Kexec going to reboot");
    reboot(LINUX_REBOOT_CMD_KEXEC);
@@ -256,6 +270,7 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg)
    char data[BOOT_MAGIC_SIZE];
    char path[PATH_MAX];
    ssize_t header_sz = 0;
    int data_fd = 0;

    D(DEBUG, "cmd_flash %s\n", arg);

@@ -273,9 +288,14 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg)
        return;
    }

    if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) {
        fastboot_fail(phandle, "Access forbiden you need certificate");
        return;
    }

    // TODO: Maybe its goot idea to check whether the partition is just bootable partition
    if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) {
        if (read_data_once(phandle->download_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) {
        if (read_data_once(data_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) {
            fastboot_fail(phandle, "incoming data read error, cannot read boot header");
            return;
        }
@@ -287,7 +307,10 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg)

    partition = flash_get_partiton(path);

    sz = get_file_size64(phandle->download_fd);
    sz = get_file_size64(data_fd);

    sz -= header_sz;

    if (sz > get_file_size64(partition)) {
        flash_close(partition);
        D(WARN, "size of file too large");
@@ -304,6 +327,8 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg)
    D(INFO, "partition '%s' updated\n", arg);

    flash_close(partition);
    close(data_fd);
    //TODO: check who is closing phandle->download_fd

    fastboot_okay(phandle, "");
}
+47 −0
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@
#include "utils.h"
#include "commands/partitions.h"

#ifdef FLASH_CERT
#include "secure.h"
#endif

#define ALLOWED_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-."
#define BUFFER_SIZE 1024 * 1024
@@ -112,3 +115,47 @@ int flash_write(int partition_fd, int data_fd, ssize_t size, ssize_t skip)

    return 0;
}

#ifdef FLASH_CERT

int flash_validate_certificate(int signed_fd, int *data_fd) {
    int ret = 0;
    const char *cert_path;
    X509_STORE *store = NULL;
    CMS_ContentInfo *content_info;
    BIO *content;

    cert_path = fastboot_getvar("certificate-path");
    if (!strcmp(cert_path, "")) {
        D(ERR, "could not find cert-key value in config file");
        goto finish;
    }

    store = cert_store_from_path(cert_path);
    if (store == NULL) {
        D(ERR, "unable to create certification store");
        goto finish;
    }

    if (cert_read(signed_fd, &content_info, &content)) {
        D(ERR, "reading data failed");
        goto finish;
    }

    ret = cert_verify(content, content_info, store, data_fd);
    cert_release(content, content_info);

    return ret;

finish:
    if (store != NULL)
        cert_release_store(store);

    return ret;
}

#else
int flash_validate_certificate(int signed_fd, int *data_fd) {
    return 1;
}
#endif
+2 −0
Original line number Diff line number Diff line
@@ -58,5 +58,7 @@ static inline ssize_t read_data_once(int fd, char *buffer, ssize_t size) {
    return readcount;
}

int flash_validate_certificate(int signed_fd, int *data_fd);

#endif
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "debug.h"
#include "trigger.h"
#include "socket_client.h"
#include "secure.h"

unsigned int debug_level = DEBUG;

@@ -72,6 +73,7 @@ int main(int argc, char **argv)
        run_socket_client();
    }
    else {
        cert_init_crypto();
        config_init();
        load_trigger();
        commands_init();
Loading