16f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo/*
26f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
36f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo *
46f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * Redistribution and use in source and binary forms, with or without
56f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * modification, are permitted provided that the following conditions are met:
66f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo *
76f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * Redistributions of source code must retain the above copyright notice, this
86f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * list of conditions and the following disclaimer.
96f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo *
106f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * Redistributions in binary form must reproduce the above copyright notice,
116f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * this list of conditions and the following disclaimer in the documentation
126f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * and/or other materials provided with the distribution.
136f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo *
146f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * Neither the name of ARM nor the names of its contributors may be used
156f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * to endorse or promote products derived from this software without specific
166f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * prior written permission.
176f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo *
186f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
196f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
206f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
216f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
226f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
236f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
246f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
256f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
266f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
276f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
286f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * POSSIBILITY OF SUCH DAMAGE.
296f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo */
306f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
316f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include <getopt.h>
326f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include <stdio.h>
336f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include <stdlib.h>
346f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include <string.h>
356f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
366f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include <openssl/conf.h>
376f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include <openssl/evp.h>
386f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include <openssl/pem.h>
396f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
406f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include "cert.h"
416f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include "debug.h"
426f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include "key.h"
436f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include "platform_oid.h"
446f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#include "sha.h"
456f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
466f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo#define MAX_FILENAME_LEN		1024
476f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
486f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo/*
496f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo * Create a new key
506f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo */
516f97162237603eb6e5c497e5ba903512bdd428a9Juan Castilloint key_new(key_t *key)
526f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo{
536f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	RSA *rsa = NULL;
546f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	EVP_PKEY *k = NULL;
556f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
566f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	/* Create key pair container */
576f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	k = EVP_PKEY_new();
586f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	if (k == NULL) {
596f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		return 0;
606f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	}
616f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
626f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	/* Generate a new RSA key */
636f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL);
646f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	if (EVP_PKEY_assign_RSA(k, rsa)) {
656f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		key->key = k;
666f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		return 1;
676f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	} else {
686f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		printf("Cannot assign RSA key\n");
696f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	}
706f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
716f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	if (k)
726f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		EVP_PKEY_free(k);
736f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	return 0;
746f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo}
756f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
766f97162237603eb6e5c497e5ba903512bdd428a9Juan Castilloint key_load(key_t *key)
776f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo{
786f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	FILE *fp = NULL;
796f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	EVP_PKEY *k = NULL;
806f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
816f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	/* Create key pair container */
826f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	k = EVP_PKEY_new();
836f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	if (k == NULL) {
846f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		return 0;
856f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	}
866f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
876f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	if (key->fn) {
886f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		/* Load key from file */
896f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		fp = fopen(key->fn, "r");
906f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		if (fp) {
916f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			k = PEM_read_PrivateKey(fp, &k, NULL, NULL);
926f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			fclose(fp);
936f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			if (k) {
946f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo				key->key = k;
956f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo				return 1;
966f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			} else {
976f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo				ERROR("Cannot read key from %s\n", key->fn);
986f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			}
996f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		} else {
1006f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			ERROR("Cannot open file %s\n", key->fn);
1016f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		}
1026f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	} else {
1036f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		ERROR("Key filename not specified\n");
1046f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	}
1056f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
1066f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	if (k)
1076f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		EVP_PKEY_free(k);
1086f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
1096f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	return 0;
1106f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo}
1116f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
1126f97162237603eb6e5c497e5ba903512bdd428a9Juan Castilloint key_store(key_t *key)
1136f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo{
1146f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	FILE *fp = NULL;
1156f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
1166f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	if (key->fn) {
1176f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		fp = fopen(key->fn, "w");
1186f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		if (fp) {
1196f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			PEM_write_PrivateKey(fp, key->key,
1206f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo					NULL, NULL, 0, NULL, NULL);
1216f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			fclose(fp);
1226f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			return 1;
1236f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		} else {
1246f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo			ERROR("Cannot create file %s\n", key->fn);
1256f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		}
1266f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	} else {
1276f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo		ERROR("Key filename not specified\n");
1286f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	}
1296f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo
1306f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo	return 0;
1316f97162237603eb6e5c497e5ba903512bdd428a9Juan Castillo}
132