aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils/mkfs.ubifs/sign.c
diff options
context:
space:
mode:
Diffstat (limited to 'ubifs-utils/mkfs.ubifs/sign.c')
-rw-r--r--ubifs-utils/mkfs.ubifs/sign.c410
1 files changed, 0 insertions, 410 deletions
diff --git a/ubifs-utils/mkfs.ubifs/sign.c b/ubifs-utils/mkfs.ubifs/sign.c
deleted file mode 100644
index 7f284f8..0000000
--- a/ubifs-utils/mkfs.ubifs/sign.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2018 Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: Sascha Hauer
- */
-
-#include "mkfs.ubifs.h"
-#include "common.h"
-
-#include <openssl/evp.h>
-#include <openssl/opensslv.h>
-#include <openssl/bio.h>
-#include <openssl/pem.h>
-#include <openssl/err.h>
-#include <openssl/engine.h>
-#include <openssl/cms.h>
-#include <openssl/conf.h>
-#include <err.h>
-
-static struct ubifs_info *c = &info_;
-
-EVP_MD_CTX *hash_md;
-const EVP_MD *md;
-
-int authenticated(void)
-{
- return c->hash_algo_name != NULL;
-}
-
-static int match_string(const char * const *array, size_t n, const char *string)
-{
- int index;
- const char *item;
-
- for (index = 0; index < n; index++) {
- item = array[index];
- if (!item)
- break;
- if (!strcmp(item, string))
- return index;
- }
-
- return -EINVAL;
-}
-
-#include <linux/hash_info.h>
-
-const char *const hash_algo_name[HASH_ALGO__LAST] = {
- [HASH_ALGO_MD4] = "md4",
- [HASH_ALGO_MD5] = "md5",
- [HASH_ALGO_SHA1] = "sha1",
- [HASH_ALGO_RIPE_MD_160] = "rmd160",
- [HASH_ALGO_SHA256] = "sha256",
- [HASH_ALGO_SHA384] = "sha384",
- [HASH_ALGO_SHA512] = "sha512",
- [HASH_ALGO_SHA224] = "sha224",
- [HASH_ALGO_RIPE_MD_128] = "rmd128",
- [HASH_ALGO_RIPE_MD_256] = "rmd256",
- [HASH_ALGO_RIPE_MD_320] = "rmd320",
- [HASH_ALGO_WP_256] = "wp256",
- [HASH_ALGO_WP_384] = "wp384",
- [HASH_ALGO_WP_512] = "wp512",
- [HASH_ALGO_TGR_128] = "tgr128",
- [HASH_ALGO_TGR_160] = "tgr160",
- [HASH_ALGO_TGR_192] = "tgr192",
- [HASH_ALGO_SM3_256] = "sm3-256",
-};
-
-static void display_openssl_errors(int l)
-{
- const char *file;
- char buf[120];
- int e, line;
-
- if (ERR_peek_error() == 0)
- return;
- fprintf(stderr, "At main.c:%d:\n", l);
-
- while ((e = ERR_get_error_line(&file, &line))) {
- ERR_error_string(e, buf);
- fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line);
- }
-}
-
-static void drain_openssl_errors(void)
-{
- const char *file;
- int line;
-
- if (ERR_peek_error() == 0)
- return;
- while (ERR_get_error_line(&file, &line)) {}
-}
-
-#define ssl_err_msg(fmt, ...) ({ \
- display_openssl_errors(__LINE__); \
- err_msg(fmt, ## __VA_ARGS__); \
- -1; \
-})
-
-static const char *key_pass;
-
-static int pem_pw_cb(char *buf, int len, __attribute__((unused)) int w,
- __attribute__((unused)) void *v)
-{
- int pwlen;
-
- if (!key_pass)
- return -1;
-
- pwlen = strlen(key_pass);
- if (pwlen >= len)
- return -1;
-
- strcpy(buf, key_pass);
-
- /* If it's wrong, don't keep trying it. */
- key_pass = NULL;
-
- return pwlen;
-}
-
-static EVP_PKEY *read_private_key(const char *private_key_name, X509 **cert)
-{
- EVP_PKEY *private_key = NULL;
- int err;
-
- *cert = NULL;
-
- if (!strncmp(private_key_name, "pkcs11:", 7)) {
- ENGINE *e;
- struct {
- const char *url;
- X509 *cert;
- } parms = {
- .url = private_key_name,
- };
-
- ENGINE_load_builtin_engines();
- drain_openssl_errors();
- e = ENGINE_by_id("pkcs11");
- if (!e) {
- ssl_err_msg("Load PKCS#11 ENGINE");
- return NULL;
- }
-
- if (ENGINE_init(e)) {
- drain_openssl_errors();
- } else {
- ssl_err_msg("ENGINE_init");
- return NULL;
- }
-
- if (key_pass)
- if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
- ssl_err_msg("Set PKCS#11 PIN");
- return NULL;
- }
-
- private_key = ENGINE_load_private_key(e, private_key_name,
- NULL, NULL);
-
- err = ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 0);
- if (!err || !parms.cert) {
- ssl_err_msg("Load certificate");
- }
- *cert = parms.cert;
- fprintf(stderr, "Using cert %p\n", *cert);
- } else {
- BIO *b;
-
- b = BIO_new_file(private_key_name, "rb");
- if (!b)
- goto out;
-
- private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb,
- NULL);
- BIO_free(b);
- }
-out:
- if (!private_key)
- ssl_err_msg("failed opening private key %s", private_key_name);
-
- return private_key;
-}
-
-static X509 *read_x509(const char *x509_name)
-{
- unsigned char buf[2];
- X509 *x509 = NULL;
- BIO *b;
- int n;
-
- b = BIO_new_file(x509_name, "rb");
- if (!b)
- goto out;
-
- /* Look at the first two bytes of the file to determine the encoding */
- n = BIO_read(b, buf, 2);
- if (n != 2) {
- if (BIO_should_retry(b))
- err_msg("%s: Read wanted retry", x509_name);
- if (n >= 0)
- err_msg("%s: Short read", x509_name);
- goto out;
- }
-
- if (BIO_reset(b))
- goto out;
-
- if (buf[0] == 0x30 && buf[1] >= 0x81 && buf[1] <= 0x84)
- /* Assume raw DER encoded X.509 */
- x509 = d2i_X509_bio(b, NULL);
- else
- /* Assume PEM encoded X.509 */
- x509 = PEM_read_bio_X509(b, NULL, NULL, NULL);
-
- BIO_free(b);
-
-out:
- if (!x509) {
- ssl_err_msg("%s", x509_name);
- return NULL;
- }
-
- return x509;
-}
-
-int sign_superblock_node(void *node)
-{
- EVP_PKEY *private_key;
- CMS_ContentInfo *cms = NULL;
- X509 *cert = NULL;
- BIO *bd, *bm;
- void *obuf;
- long len;
- int ret;
- void *pret;
- struct ubifs_sig_node *sig = node + UBIFS_SB_NODE_SZ;
-
- if (!authenticated())
- return 0;
-
- ERR_load_crypto_strings();
- ERR_clear_error();
-
- key_pass = getenv("MKFS_UBIFS_SIGN_PIN");
-
- bm = BIO_new_mem_buf(node, UBIFS_SB_NODE_SZ);
-
- private_key = read_private_key(c->auth_key_filename, &cert);
- if (!private_key)
- return -1;
-
- if (!cert) {
- if (!c->auth_cert_filename)
- return err_msg("authentication certificate not provided (--auth-cert)");
- cert = read_x509(c->auth_cert_filename);
- }
-
- if (!cert)
- return -1;
-
- OpenSSL_add_all_digests();
- display_openssl_errors(__LINE__);
-
- cms = CMS_sign(NULL, NULL, NULL, NULL,
- CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY |
- CMS_DETACHED | CMS_STREAM);
- if (!cms)
- return err_msg("CMS_sign failed");
-
- pret = CMS_add1_signer(cms, cert, private_key, md,
- CMS_NOCERTS | CMS_BINARY |
- CMS_NOSMIMECAP | CMS_NOATTR);
- if (!pret)
- return err_msg("CMS_add1_signer failed");
-
- ret = CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY);
- if (!ret)
- return err_msg("CMS_final failed");
-
- bd = BIO_new(BIO_s_mem());
-
- ret = i2d_CMS_bio_stream(bd, cms, NULL, 0);
- if (!ret)
- return err_msg("i2d_CMS_bio_stream failed");
-
- len = BIO_get_mem_data(bd, &obuf);
-
- sig->type = UBIFS_SIGNATURE_TYPE_PKCS7;
- sig->len = cpu_to_le32(len);
- sig->ch.node_type = UBIFS_SIG_NODE;
-
- memcpy(sig + 1, obuf, len);
-
- BIO_free(bd);
- BIO_free(bm);
-
- return 0;
-}
-
-/**
- * ubifs_node_calc_hash - calculate the hash of a UBIFS node
- * @c: UBIFS file-system description object
- * @node: the node to calculate a hash for
- * @hash: the returned hash
- */
-void ubifs_node_calc_hash(const void *node, uint8_t *hash)
-{
- const struct ubifs_ch *ch = node;
- unsigned int md_len;
-
- if (!authenticated())
- return;
-
- EVP_DigestInit_ex(hash_md, md, NULL);
- EVP_DigestUpdate(hash_md, node, le32_to_cpu(ch->len));
- EVP_DigestFinal_ex(hash_md, hash, &md_len);
-}
-
-/**
- * mst_node_calc_hash - calculate the hash of a UBIFS master node
- * @c: UBIFS file-system description object
- * @node: the node to calculate a hash for
- * @hash: the returned hash
- */
-void mst_node_calc_hash(const void *node, uint8_t *hash)
-{
- unsigned int md_len;
-
- if (!authenticated())
- return;
-
- EVP_DigestInit_ex(hash_md, md, NULL);
- EVP_DigestUpdate(hash_md, node + sizeof(struct ubifs_ch),
- UBIFS_MST_NODE_SZ - sizeof(struct ubifs_ch));
- EVP_DigestFinal_ex(hash_md, hash, &md_len);
-}
-
-void hash_digest_init(void)
-{
- if (!authenticated())
- return;
-
- EVP_DigestInit_ex(hash_md, md, NULL);
-}
-
-void hash_digest_update(const void *buf, int len)
-{
- if (!authenticated())
- return;
-
- EVP_DigestUpdate(hash_md, buf, len);
-}
-
-void hash_digest_final(void *hash, unsigned int *len)
-{
- if (!authenticated())
- return;
-
- EVP_DigestFinal_ex(hash_md, hash, len);
-}
-
-int init_authentication(void)
-{
- int hash_algo;
-
- if (!c->auth_key_filename && !c->auth_cert_filename && !c->hash_algo_name)
- return 0;
-
- if (!c->auth_key_filename)
- return err_msg("authentication key not given (--auth-key)");
-
- if (!c->hash_algo_name)
- return err_msg("Hash algorithm not given (--hash-algo)");
-
- OPENSSL_config(NULL);
-
- OpenSSL_add_all_algorithms();
- ERR_load_crypto_strings();
-
- md = EVP_get_digestbyname(c->hash_algo_name);
- if (!md)
- return err_msg("Unknown message digest %s", c->hash_algo_name);
-
- hash_md = EVP_MD_CTX_create();
- c->hash_len = EVP_MD_size(md);
-
- hash_algo = match_string(hash_algo_name, HASH_ALGO__LAST, c->hash_algo_name);
- if (hash_algo < 0)
- return err_msg("Unsupported message digest %s", c->hash_algo_name);
-
- c->hash_algo = hash_algo;
-
- return 0;
-}