/* Copyright 2011 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Host functions for signature generation.
 */

/* TODO: change all 'return 0', 'return 1' into meaningful return codes */

#include <openssl/rsa.h>

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "2common.h"
#include "2rsa.h"
#include "2sha.h"
#include "2sysincludes.h"
#include "host_common.h"
#include "host_signature21.h"

/* Invoke [external_signer] command with [pem_file] as an argument, contents of
 * [inbuf] passed redirected to stdin, and the stdout of the command is put
 * back into [outbuf].  Returns -1 on error, 0 on success.
 */
static int sign_external(uint32_t size, const uint8_t *inbuf, uint8_t *outbuf,
			 uint32_t outbufsize, const char *pem_file,
			 const char *external_signer)
{
	int rv = 0, n;
	int p_to_c[2], c_to_p[2];  /* pipe descriptors */
	pid_t pid;

	VB2_DEBUG("Will invoke \"%s %s\" to perform signing.\n"
		 "Input to the signer will be provided on standard in.\n"
		 "Output of the signer will be read from standard out.\n",
		  external_signer, pem_file);

	/* Need two pipes since we want to invoke the external_signer as
	 * a co-process writing to its stdin and reading from its stdout. */
	if (pipe(p_to_c) < 0 || pipe(c_to_p) < 0) {
		VB2_DEBUG("pipe() error\n");
		return -1;
	}
	if ((pid = fork()) < 0) {
		VB2_DEBUG("fork() error\n");
		return -1;
	} else if (pid > 0) {  /* Parent. */
		close(p_to_c[STDIN_FILENO]);
		close(c_to_p[STDOUT_FILENO]);

		/* We provide input to the child process (external signer). */
		if (write(p_to_c[STDOUT_FILENO], inbuf, size) != size) {
			VB2_DEBUG("write() error\n");
			rv = -1;
		} else {
			/* Send EOF to child (signer process). */
			close(p_to_c[STDOUT_FILENO]);

			do {
				n = read(c_to_p[STDIN_FILENO], outbuf,
					 outbufsize);
				outbuf += n;
				outbufsize -= n;
			} while (n > 0 && outbufsize);

			if (n < 0) {
				VB2_DEBUG("read() error\n");
				rv = -1;
			}
		}
		if (waitpid(pid, NULL, 0) < 0) {
			VB2_DEBUG("waitpid() error\n");
			rv = -1;
		}
	} else {  /* Child. */
		close (p_to_c[STDOUT_FILENO]);
		close (c_to_p[STDIN_FILENO]);
		/* Map the stdin to the first pipe (this pipe gets input
		 * from the parent) */
		if (STDIN_FILENO != p_to_c[STDIN_FILENO]) {
			if (dup2(p_to_c[STDIN_FILENO], STDIN_FILENO) !=
			    STDIN_FILENO) {
				VB2_DEBUG("stdin dup2() failed\n");
				close(p_to_c[0]);
				return -1;
			}
		}
		/* Map the stdout to the second pipe (this pipe sends back
		 * signer output to the parent) */
		if (STDOUT_FILENO != c_to_p[STDOUT_FILENO]) {
			if (dup2(c_to_p[STDOUT_FILENO], STDOUT_FILENO) !=
			    STDOUT_FILENO) {
				VB2_DEBUG("stdout dup2() failed\n");
				close(c_to_p[STDOUT_FILENO]);
				return -1;
			}
		}
		/* External signer is invoked here. */
		if (execl(external_signer, external_signer, pem_file,
			  (char *) 0) < 0) {
			VB2_DEBUG("execl() of external signer failed\n");
		}
	}
	return rv;
}

struct vb2_signature *vb2_external_signature(const uint8_t *data, uint32_t size,
					     const char *key_file,
					     uint32_t key_algorithm,
					     const char *external_signer)
{
	struct vb2_hash hash;

	/* Calculate the digest */
	if (VB2_SUCCESS != vb2_hash_calculate(false, data, size,
					      vb2_crypto_to_hash(key_algorithm),
					      &hash))
		return NULL;

	uint32_t digest_info_size = 0;
	const uint8_t *digest_info = NULL;
	if (VB2_SUCCESS != vb2_digest_info(hash.algo,
					   &digest_info, &digest_info_size))
		return NULL;

	int digest_size = vb2_digest_size(hash.algo);
	uint8_t *signature_digest;
	uint64_t signature_digest_len = digest_size + digest_info_size;

	int rv;

	/* Prepend the digest info to the digest */
	signature_digest = calloc(signature_digest_len, 1);
	if (!signature_digest)
		return NULL;

	memcpy(signature_digest, digest_info, digest_info_size);
	memcpy(signature_digest + digest_info_size, hash.raw, digest_size);

	/* Allocate output signature */
	uint32_t sig_size =
		vb2_rsa_sig_size(vb2_crypto_to_signature(key_algorithm));
	struct vb2_signature *sig = vb2_alloc_signature(sig_size, size);
	if (!sig) {
		free(signature_digest);
		return NULL;
	}

	/* Sign the signature_digest into our output buffer */
	rv = sign_external(signature_digest_len,    /* Input length */
			   signature_digest,        /* Input data */
			   vb2_signature_data_mutable(sig),  /* Output sig */
			   sig_size,                /* Max Output sig size */
			   key_file,                /* Key file to use */
			   external_signer);        /* External cmd to invoke */
	free(signature_digest);

	if (-1 == rv) {
		VB2_DEBUG("RSA_private_encrypt() failed.\n");
		free(sig);
		return NULL;
	}

	/* Return the signature */
	return sig;
}
