OSDN Git Service

Merge "simpleperf: add test for dumping regs for tracepoint events." am: 87fcb8c6c1...
[android-x86/system-extras.git] / verity / generate_verity_key.c
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define _GNU_SOURCE  /* needed for asprintf */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25
26 #include <crypto_utils/android_pubkey.h>
27
28 #include <openssl/evp.h>
29 #include <openssl/objects.h>
30 #include <openssl/pem.h>
31 #include <openssl/rsa.h>
32 #include <openssl/sha.h>
33
34 static int write_public_keyfile(RSA *private_key, const char *private_key_path)
35 {
36     uint8_t key_data[ANDROID_PUBKEY_ENCODED_SIZE];
37     BIO *bfile = NULL;
38     char *path = NULL;
39     int ret = -1;
40
41     if (asprintf(&path, "%s.pub", private_key_path) < 0)
42         goto out;
43
44     if (!android_pubkey_encode(private_key, key_data, sizeof(key_data)))
45         goto out;
46
47     bfile = BIO_new_file(path, "w");
48     if (!bfile)
49         goto out;
50
51     BIO_write(bfile, key_data, sizeof(key_data));
52     BIO_flush(bfile);
53
54     ret = 0;
55 out:
56     BIO_free_all(bfile);
57     free(path);
58     return ret;
59 }
60
61 static int convert_x509(const char *pem_file, const char *key_file)
62 {
63     int ret = -1;
64     FILE *f = NULL;
65     EVP_PKEY *pkey = NULL;
66     RSA *rsa = NULL;
67     X509 *cert = NULL;
68
69     if (!pem_file || !key_file) {
70         goto out;
71     }
72
73     f = fopen(pem_file, "r");
74     if (!f) {
75         printf("Failed to open '%s'\n", pem_file);
76         goto out;
77     }
78
79     cert = PEM_read_X509(f, &cert, NULL, NULL);
80     if (!cert) {
81         printf("Failed to read PEM certificate from file '%s'\n", pem_file);
82         goto out;
83     }
84
85     pkey = X509_get_pubkey(cert);
86     if (!pkey) {
87         printf("Failed to extract public key from certificate '%s'\n", pem_file);
88         goto out;
89     }
90
91     rsa = EVP_PKEY_get1_RSA(pkey);
92     if (!rsa) {
93         printf("Failed to get the RSA public key from '%s'\n", pem_file);
94         goto out;
95     }
96
97     if (write_public_keyfile(rsa, key_file) < 0) {
98         printf("Failed to write public key\n");
99         goto out;
100     }
101
102     ret = 0;
103
104 out:
105     if (f) {
106         fclose(f);
107     }
108     if (cert) {
109         X509_free(cert);
110     }
111     if (pkey) {
112         EVP_PKEY_free(pkey);
113     }
114     if (rsa) {
115         RSA_free(rsa);
116     }
117
118     return ret;
119 }
120
121 static int generate_key(const char *file)
122 {
123     int ret = -1;
124     FILE *f = NULL;
125     RSA* rsa = RSA_new();
126     BIGNUM* exponent = BN_new();
127     EVP_PKEY* pkey = EVP_PKEY_new();
128
129     if (!pkey || !exponent || !rsa) {
130         printf("Failed to allocate key\n");
131         goto out;
132     }
133
134     BN_set_word(exponent, RSA_F4);
135     RSA_generate_key_ex(rsa, 2048, exponent, NULL);
136     EVP_PKEY_set1_RSA(pkey, rsa);
137
138     f = fopen(file, "w");
139     if (!f) {
140         printf("Failed to open '%s'\n", file);
141         goto out;
142     }
143
144     if (!PEM_write_PrivateKey(f, pkey, NULL, NULL, 0, NULL, NULL)) {
145         printf("Failed to write key\n");
146         goto out;
147     }
148
149     if (write_public_keyfile(rsa, file) < 0) {
150         printf("Failed to write public key\n");
151         goto out;
152     }
153
154     ret = 0;
155
156 out:
157     if (f)
158         fclose(f);
159     EVP_PKEY_free(pkey);
160     RSA_free(rsa);
161     BN_free(exponent);
162     return ret;
163 }
164
165 static void usage(){
166     printf("Usage: generate_verity_key <path-to-key> | -convert <path-to-x509-pem> <path-to-key>\n");
167 }
168
169 int main(int argc, char *argv[]) {
170     if (argc == 2) {
171         return generate_key(argv[1]);
172     } else if (argc == 4 && !strcmp(argv[1], "-convert")) {
173         return convert_x509(argv[2], argv[3]);
174     } else {
175         usage();
176         exit(-1);
177     }
178 }