// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
 * Copyright (C) 2025 Google LLC.
 */

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <getopt.h>
#include <err.h>
#include <openssl/opensslv.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include <linux/keyctl.h>
#include <errno.h>

#include <bpf/skel_internal.h>

#include "main.h"

#define OPEN_SSL_ERR_BUF_LEN 256

/* Use deprecated in 3.0 ERR_get_error_line_data for openssl < 3 */
#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
#define ERR_get_error_all(file, line, func, data, flags) \
	ERR_get_error_line_data(file, line, data, flags)
#endif

static void display_openssl_errors(int l)
{
	char buf[OPEN_SSL_ERR_BUF_LEN];
	const char *file;
	const char *data;
	unsigned long e;
	int flags;
	int line;

	while ((e = ERR_get_error_all(&file, &line, NULL, &data, &flags))) {
		ERR_error_string_n(e, buf, sizeof(buf));
		if (data && (flags & ERR_TXT_STRING)) {
			p_err("OpenSSL %s: %s:%d: %s", buf, file, line, data);
		} else {
			p_err("OpenSSL %s: %s:%d", buf, file, line);
		}
	}
}

#define DISPLAY_OSSL_ERR(cond)				 \
	do {						 \
		bool __cond = (cond);			 \
		if (__cond && ERR_peek_error())		 \
			display_openssl_errors(__LINE__);\
	} while (0)

static EVP_PKEY *read_private_key(const char *pkey_path)
{
	EVP_PKEY *private_key = NULL;
	BIO *b;

	b = BIO_new_file(pkey_path, "rb");
	private_key = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
	BIO_free(b);
	DISPLAY_OSSL_ERR(!private_key);
	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 cleanup;

	/* Look at the first two bytes of the file to determine the encoding */
	n = BIO_read(b, buf, 2);
	if (n != 2)
		goto cleanup;

	if (BIO_reset(b) != 0)
		goto cleanup;

	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);

cleanup:
	BIO_free(b);
	DISPLAY_OSSL_ERR(!x509);
	return x509;
}

__u32 register_session_key(const char *key_der_path)
{
	unsigned char *der_buf = NULL;
	X509 *x509 = NULL;
	int key_id = -1;
	int der_len;

	if (!key_der_path)
		return key_id;
	x509 = read_x509(key_der_path);
	if (!x509)
		goto cleanup;
	der_len = i2d_X509(x509, &der_buf);
	if (der_len < 0)
		goto cleanup;
	key_id = syscall(__NR_add_key, "asymmetric", key_der_path, der_buf,
			     (size_t)der_len, KEY_SPEC_SESSION_KEYRING);
cleanup:
	X509_free(x509);
	OPENSSL_free(der_buf);
	DISPLAY_OSSL_ERR(key_id == -1);
	return key_id;
}

int bpftool_prog_sign(struct bpf_load_and_run_opts *opts)
{
	BIO *bd_in = NULL, *bd_out = NULL;
	EVP_PKEY *private_key = NULL;
	CMS_ContentInfo *cms = NULL;
	long actual_sig_len = 0;
	X509 *x509 = NULL;
	void *data = NULL;
	size_t data_sz;
	int err = 0;

	data_sz = (size_t)opts->insns_sz + opts->data_sz;
	data = malloc(data_sz);
	if (!data) {
		err = -ENOMEM;
		goto cleanup;
	}
	memcpy(data, opts->insns, opts->insns_sz);
	if (opts->data_sz)
		memcpy((char *)data + opts->insns_sz, opts->data, opts->data_sz);

	bd_in = BIO_new_mem_buf(data, data_sz);
	if (!bd_in) {
		err = -ENOMEM;
		goto cleanup;
	}

	private_key = read_private_key(private_key_path);
	if (!private_key) {
		err = -EINVAL;
		goto cleanup;
	}

	x509 = read_x509(cert_path);
	if (!x509) {
		err = -EINVAL;
		goto cleanup;
	}

	cms = CMS_sign(NULL, NULL, NULL, NULL,
		       CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY | CMS_DETACHED |
			       CMS_STREAM);
	if (!cms) {
		err = -EINVAL;
		goto cleanup;
	}

	if (!CMS_add1_signer(cms, x509, private_key, EVP_sha256(),
			     CMS_NOCERTS | CMS_BINARY | CMS_NOSMIMECAP |
			     CMS_USE_KEYID | CMS_NOATTR)) {
		err = -EINVAL;
		goto cleanup;
	}

	if (CMS_final(cms, bd_in, NULL, CMS_NOCERTS | CMS_BINARY) != 1) {
		err = -EIO;
		goto cleanup;
	}

	if (EVP_Digest(opts->insns, opts->insns_sz, opts->excl_prog_hash,
		       &opts->excl_prog_hash_sz, EVP_sha256(), NULL) != 1) {
		err = -EIO;
		goto cleanup;
	}

	bd_out = BIO_new(BIO_s_mem());
	if (!bd_out) {
		err = -ENOMEM;
		goto cleanup;
	}

	if (!i2d_CMS_bio_stream(bd_out, cms, NULL, 0)) {
		err = -EIO;
		goto cleanup;
	}

	actual_sig_len = BIO_get_mem_data(bd_out, NULL);
	if (actual_sig_len <= 0) {
		err = -EIO;
		goto cleanup;
	}

	if ((size_t)actual_sig_len > opts->signature_sz) {
		err = -ENOSPC;
		goto cleanup;
	}

	if (BIO_read(bd_out, opts->signature, actual_sig_len) != actual_sig_len) {
		err = -EIO;
		goto cleanup;
	}

	opts->signature_sz = actual_sig_len;
cleanup:
	BIO_free(bd_out);
	CMS_ContentInfo_free(cms);
	X509_free(x509);
	EVP_PKEY_free(private_key);
	BIO_free(bd_in);
	free(data);
	DISPLAY_OSSL_ERR(err < 0);
	return err;
}
