xref: /rk3399_ARM-atf/tools/cert_create/src/key.c (revision 1779ba6b97fbff87290f164c7c78559329173e02)
1 /*
2  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <getopt.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #include <openssl/conf.h>
37 #include <openssl/evp.h>
38 #include <openssl/pem.h>
39 
40 #include "cert.h"
41 #include "debug.h"
42 #include "key.h"
43 #include "platform_oid.h"
44 #include "sha.h"
45 
46 #define MAX_FILENAME_LEN		1024
47 
48 /*
49  * Create a new key container
50  */
51 static int key_new(key_t *key)
52 {
53 	/* Create key pair container */
54 	key->key = EVP_PKEY_new();
55 	if (key->key == NULL) {
56 		return 0;
57 	}
58 
59 	return 1;
60 }
61 
62 int key_create(key_t *key, int type)
63 {
64 	RSA *rsa = NULL;
65 	EC_KEY *ec = NULL;
66 
67 	/* Create OpenSSL key container */
68 	if (!key_new(key)) {
69 		goto err;
70 	}
71 
72 	switch (type) {
73 	case KEY_ALG_RSA:
74 		/* Generate a new RSA key */
75 		rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL);
76 		if (rsa == NULL) {
77 			printf("Cannot create RSA key\n");
78 			goto err;
79 		}
80 		if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
81 			printf("Cannot assign RSA key\n");
82 			goto err;
83 		}
84 		break;
85 	case KEY_ALG_ECDSA:
86 		/* Generate a new ECDSA key */
87 		ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
88 		if (ec == NULL) {
89 			printf("Cannot create EC key\n");
90 			goto err;
91 		}
92 		if (!EC_KEY_generate_key(ec)) {
93 			printf("Cannot generate EC key\n");
94 			goto err;
95 		}
96 		EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
97 		EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
98 		if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
99 			printf("Cannot assign EC key\n");
100 			goto err;
101 		}
102 		break;
103 	default:
104 		goto err;
105 	}
106 
107 	return 1;
108 
109 err:
110 	RSA_free(rsa);
111 	EC_KEY_free(ec);
112 
113 	return 0;
114 }
115 
116 int key_load(key_t *key, unsigned int *err_code)
117 {
118 	FILE *fp = NULL;
119 	EVP_PKEY *k = NULL;
120 
121 	/* Create OpenSSL key container */
122 	if (!key_new(key)) {
123 		*err_code = KEY_ERR_MALLOC;
124 		return 0;
125 	}
126 
127 	if (key->fn) {
128 		/* Load key from file */
129 		fp = fopen(key->fn, "r");
130 		if (fp) {
131 			k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL);
132 			fclose(fp);
133 			if (k) {
134 				*err_code = KEY_ERR_NONE;
135 				return 1;
136 			} else {
137 				ERROR("Cannot load key from %s\n", key->fn);
138 				*err_code = KEY_ERR_LOAD;
139 			}
140 		} else {
141 			WARN("Cannot open file %s\n", key->fn);
142 			*err_code = KEY_ERR_OPEN;
143 		}
144 	} else {
145 		WARN("Key filename not specified\n");
146 		*err_code = KEY_ERR_FILENAME;
147 	}
148 
149 	return 0;
150 }
151 
152 int key_store(key_t *key)
153 {
154 	FILE *fp = NULL;
155 
156 	if (key->fn) {
157 		fp = fopen(key->fn, "w");
158 		if (fp) {
159 			PEM_write_PrivateKey(fp, key->key,
160 					NULL, NULL, 0, NULL, NULL);
161 			fclose(fp);
162 			return 1;
163 		} else {
164 			ERROR("Cannot create file %s\n", key->fn);
165 		}
166 	} else {
167 		ERROR("Key filename not specified\n");
168 	}
169 
170 	return 0;
171 }
172