• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Key reading application
3  *
4  *  Copyright The Mbed TLS Contributors
5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6  */
7 
8 #if !defined(MBEDTLS_CONFIG_FILE)
9 #include "mbedtls/config.h"
10 #else
11 #include MBEDTLS_CONFIG_FILE
12 #endif
13 
14 #include "mbedtls/platform.h"
15 
16 #if defined(MBEDTLS_BIGNUM_C) && \
17     defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_FS_IO)
18 #include "mbedtls/error.h"
19 #include "mbedtls/rsa.h"
20 #include "mbedtls/pk.h"
21 
22 #include <string.h>
23 #endif
24 
25 #define MODE_NONE               0
26 #define MODE_PRIVATE            1
27 #define MODE_PUBLIC             2
28 
29 #define DFL_MODE                MODE_NONE
30 #define DFL_FILENAME            "keyfile.key"
31 #define DFL_PASSWORD            ""
32 #define DFL_PASSWORD_FILE       ""
33 #define DFL_DEBUG_LEVEL         0
34 
35 #define USAGE \
36     "\n usage: key_app param=<>...\n"                   \
37     "\n acceptable parameters:\n"                       \
38     "    mode=private|public default: none\n"           \
39     "    filename=%%s         default: keyfile.key\n"   \
40     "    password=%%s         default: \"\"\n"          \
41     "    password_file=%%s    default: \"\"\n"          \
42     "\n"
43 
44 #if !defined(MBEDTLS_BIGNUM_C) ||                                  \
45     !defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_FS_IO)
main(void)46 int main(void)
47 {
48     mbedtls_printf("MBEDTLS_BIGNUM_C and/or "
49                    "MBEDTLS_PK_PARSE_C and/or MBEDTLS_FS_IO not defined.\n");
50     mbedtls_exit(0);
51 }
52 #else
53 
54 
55 /*
56  * global options
57  */
58 struct options {
59     int mode;                   /* the mode to run the application in   */
60     const char *filename;       /* filename of the key file             */
61     const char *password;       /* password for the private key         */
62     const char *password_file;  /* password_file for the private key    */
63 } opt;
64 
main(int argc,char * argv[])65 int main(int argc, char *argv[])
66 {
67     int ret = 1;
68     int exit_code = MBEDTLS_EXIT_FAILURE;
69     char buf[1024];
70     int i;
71     char *p, *q;
72 
73     mbedtls_pk_context pk;
74     mbedtls_mpi N, P, Q, D, E, DP, DQ, QP;
75 
76     /*
77      * Set to sane values
78      */
79     mbedtls_pk_init(&pk);
80     memset(buf, 0, sizeof(buf));
81 
82 #if defined(MBEDTLS_USE_PSA_CRYPTO)
83     psa_status_t status = psa_crypto_init();
84     if (status != PSA_SUCCESS) {
85         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
86                         (int) status);
87         goto cleanup;
88     }
89 #endif /* MBEDTLS_USE_PSA_CRYPTO */
90 
91     mbedtls_mpi_init(&N); mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
92     mbedtls_mpi_init(&D); mbedtls_mpi_init(&E); mbedtls_mpi_init(&DP);
93     mbedtls_mpi_init(&DQ); mbedtls_mpi_init(&QP);
94 
95     if (argc < 2) {
96 usage:
97         mbedtls_printf(USAGE);
98         goto cleanup;
99     }
100 
101     opt.mode                = DFL_MODE;
102     opt.filename            = DFL_FILENAME;
103     opt.password            = DFL_PASSWORD;
104     opt.password_file       = DFL_PASSWORD_FILE;
105 
106     for (i = 1; i < argc; i++) {
107         p = argv[i];
108         if ((q = strchr(p, '=')) == NULL) {
109             goto usage;
110         }
111         *q++ = '\0';
112 
113         if (strcmp(p, "mode") == 0) {
114             if (strcmp(q, "private") == 0) {
115                 opt.mode = MODE_PRIVATE;
116             } else if (strcmp(q, "public") == 0) {
117                 opt.mode = MODE_PUBLIC;
118             } else {
119                 goto usage;
120             }
121         } else if (strcmp(p, "filename") == 0) {
122             opt.filename = q;
123         } else if (strcmp(p, "password") == 0) {
124             opt.password = q;
125         } else if (strcmp(p, "password_file") == 0) {
126             opt.password_file = q;
127         } else {
128             goto usage;
129         }
130     }
131 
132     if (opt.mode == MODE_PRIVATE) {
133         if (strlen(opt.password) && strlen(opt.password_file)) {
134             mbedtls_printf("Error: cannot have both password and password_file\n");
135             goto usage;
136         }
137 
138         if (strlen(opt.password_file)) {
139             FILE *f;
140 
141             mbedtls_printf("\n  . Loading the password file ...");
142             if ((f = fopen(opt.password_file, "rb")) == NULL) {
143                 mbedtls_printf(" failed\n  !  fopen returned NULL\n");
144                 goto cleanup;
145             }
146             if (fgets(buf, sizeof(buf), f) == NULL) {
147                 fclose(f);
148                 mbedtls_printf("Error: fgets() failed to retrieve password\n");
149                 goto cleanup;
150             }
151             fclose(f);
152 
153             i = (int) strlen(buf);
154             if (buf[i - 1] == '\n') {
155                 buf[i - 1] = '\0';
156             }
157             if (buf[i - 2] == '\r') {
158                 buf[i - 2] = '\0';
159             }
160             opt.password = buf;
161         }
162 
163         /*
164          * 1.1. Load the key
165          */
166         mbedtls_printf("\n  . Loading the private key ...");
167         fflush(stdout);
168 
169         ret = mbedtls_pk_parse_keyfile(&pk, opt.filename, opt.password);
170 
171         if (ret != 0) {
172             mbedtls_printf(" failed\n  !  mbedtls_pk_parse_keyfile returned -0x%04x\n",
173                            (unsigned int) -ret);
174             goto cleanup;
175         }
176 
177         mbedtls_printf(" ok\n");
178 
179         /*
180          * 1.2 Print the key
181          */
182         mbedtls_printf("  . Key information    ...\n");
183 #if defined(MBEDTLS_RSA_C)
184         if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_RSA) {
185             mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
186 
187             if ((ret = mbedtls_rsa_export(rsa, &N, &P, &Q, &D, &E)) != 0 ||
188                 (ret = mbedtls_rsa_export_crt(rsa, &DP, &DQ, &QP))      != 0) {
189                 mbedtls_printf(" failed\n  ! could not export RSA parameters\n\n");
190                 goto cleanup;
191             }
192 
193             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("N:  ", &N, 16, NULL));
194             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("E:  ", &E, 16, NULL));
195             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("D:  ", &D, 16, NULL));
196             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("P:  ", &P, 16, NULL));
197             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q:  ", &Q, 16, NULL));
198             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("DP: ", &DP, 16, NULL));
199             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("DQ:  ", &DQ, 16, NULL));
200             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("QP:  ", &QP, 16, NULL));
201         } else
202 #endif
203 #if defined(MBEDTLS_ECP_C)
204         if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY) {
205             mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(pk);
206             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(X): ", &ecp->Q.X, 16, NULL));
207             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Y): ", &ecp->Q.Y, 16, NULL));
208             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Z): ", &ecp->Q.Z, 16, NULL));
209             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("D   : ", &ecp->d, 16, NULL));
210         } else
211 #endif
212         {
213             mbedtls_printf("Do not know how to print key information for this type\n");
214             goto cleanup;
215         }
216     } else if (opt.mode == MODE_PUBLIC) {
217         /*
218          * 1.1. Load the key
219          */
220         mbedtls_printf("\n  . Loading the public key ...");
221         fflush(stdout);
222 
223         ret = mbedtls_pk_parse_public_keyfile(&pk, opt.filename);
224 
225         if (ret != 0) {
226             mbedtls_printf(" failed\n  !  mbedtls_pk_parse_public_keyfile returned -0x%04x\n",
227                            (unsigned int) -ret);
228             goto cleanup;
229         }
230 
231         mbedtls_printf(" ok\n");
232 
233         mbedtls_printf("  . Key information    ...\n");
234 #if defined(MBEDTLS_RSA_C)
235         if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_RSA) {
236             mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
237 
238             if ((ret = mbedtls_rsa_export(rsa, &N, NULL, NULL,
239                                           NULL, &E)) != 0) {
240                 mbedtls_printf(" failed\n  ! could not export RSA parameters\n\n");
241                 goto cleanup;
242             }
243             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("N:  ", &N, 16, NULL));
244             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("E:  ", &E, 16, NULL));
245         } else
246 #endif
247 #if defined(MBEDTLS_ECP_C)
248         if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY) {
249             mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(pk);
250             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(X): ", &ecp->Q.X, 16, NULL));
251             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Y): ", &ecp->Q.Y, 16, NULL));
252             MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Z): ", &ecp->Q.Z, 16, NULL));
253         } else
254 #endif
255         {
256             mbedtls_printf("Do not know how to print key information for this type\n");
257             goto cleanup;
258         }
259     } else {
260         goto usage;
261     }
262 
263     exit_code = MBEDTLS_EXIT_SUCCESS;
264 
265 cleanup:
266 
267 #if defined(MBEDTLS_ERROR_C)
268     if (exit_code != MBEDTLS_EXIT_SUCCESS) {
269         mbedtls_strerror(ret, buf, sizeof(buf));
270         mbedtls_printf("  !  Last error was: %s\n", buf);
271     }
272 #endif
273 
274     mbedtls_pk_free(&pk);
275 #if defined(MBEDTLS_USE_PSA_CRYPTO)
276     mbedtls_psa_crypto_free();
277 #endif /* MBEDTLS_USE_PSA_CRYPTO */
278     mbedtls_mpi_free(&N); mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
279     mbedtls_mpi_free(&D); mbedtls_mpi_free(&E); mbedtls_mpi_free(&DP);
280     mbedtls_mpi_free(&DQ); mbedtls_mpi_free(&QP);
281 
282 #if defined(_WIN32)
283     mbedtls_printf("  + Press Enter to exit this program.\n");
284     fflush(stdout); getchar();
285 #endif
286 
287     mbedtls_exit(exit_code);
288 }
289 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO */
290