Fix CVE-2017-6891 in minitasn1 code
[platform/upstream/gnutls.git] / src / certtool-extras.c
1 /*
2  * Copyright (C) 2012 Lucas Fisher *lucas.fisher [at] gmail.com*
3  * Copyright (C) 2012 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuTLS.
6  *
7  * GnuTLS is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuTLS is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see
19  * <http://www.gnu.org/licenses/>.
20  *
21  * In addition, as a special exception, the copyright holders give
22  * permission to link the code of portions of this program with the
23  * OpenSSL library under certain conditions as described in each
24  * individual source file, and distribute linked combinations including
25  * the two.
26  * 
27  * You must obey the GNU General Public License in all respects for all
28  * of the code used other than OpenSSL. If you modify file(s) with this
29  * exception, you may extend this exception to your version of the
30  * file(s), but you are not obligated to do so. If you do not wish to do
31  * so, delete this exception statement from your version. If you delete
32  * this exception statement from all source files in the program, then
33  * also delete it here.
34  */
35
36 #include <config.h>
37
38 #include <gnutls/gnutls.h>
39 #include <gnutls/x509.h>
40 #include <gnutls/openpgp.h>
41 #include <gnutls/pkcs12.h>
42 #include <gnutls/pkcs11.h>
43 #include <gnutls/abstract.h>
44
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <ctype.h>
49 #include <time.h>
50 #include <unistd.h>
51 #include <errno.h>
52 #include <sys/types.h>
53 #include <sys/stat.h>
54 #include <fcntl.h>
55 #include "certtool-common.h"
56 #include "certtool-cfg.h"
57
58
59 #define MAX_KEYS 256
60
61 /* Loads a x509 private key list
62  */
63 gnutls_x509_privkey_t *load_privkey_list(int mand, size_t * privkey_size,
64                                          common_info_st * info)
65 {
66         static gnutls_x509_privkey_t key[MAX_KEYS];
67         char *ptr;
68         int ret, i;
69         gnutls_datum_t dat, file_data;
70         int ptr_size;
71         unsigned int flags = 0;
72         const char *pass;
73
74         *privkey_size = 0;
75         fprintf(stderr, "Loading private key list...\n");
76
77         if (info->privkey == NULL) {
78                 if (mand) {
79                         fprintf(stderr, "missing --load-privkey");
80                         exit(1);
81                 } else
82                         return NULL;
83         }
84
85         ret = gnutls_load_file(info->privkey, &file_data);
86         if (ret < 0) {
87                 fprintf(stderr, "%s", info->privkey);
88                 exit(1);
89         }
90
91         ptr = (void *) file_data.data;
92         ptr_size = file_data.size;
93
94         for (i = 0; i < MAX_KEYS; i++) {
95                 ret = gnutls_x509_privkey_init(&key[i]);
96                 if (ret < 0) {
97                         fprintf(stderr, "privkey_init: %s",
98                                 gnutls_strerror(ret));
99                         exit(1);
100                 }
101
102                 dat.data = (void *) ptr;
103                 dat.size = ptr_size;
104
105                 ret =
106                     gnutls_x509_privkey_import2(key[i], &dat,
107                                                 info->incert_format, NULL,
108                                                 0);
109                 if (ret == GNUTLS_E_DECRYPTION_FAILED) {
110                         pass = get_password(info, &flags, 0);
111                         ret =
112                             gnutls_x509_privkey_import2(key[i], &dat,
113                                                         info->
114                                                         incert_format,
115                                                         pass, flags);
116                 }
117
118                 if (ret < 0 && *privkey_size > 0)
119                         break;
120                 if (ret < 0) {
121                         fprintf(stderr, "privkey_import: %s",
122                                 gnutls_strerror(ret));
123                         exit(1);
124                 }
125
126                 (*privkey_size)++;
127
128                 if (info->incert_format != GNUTLS_X509_FMT_PEM)
129                         break;
130
131                 ptr = strstr(ptr, "---END");
132                 if (ptr == NULL)
133                         break;
134                 ptr++;
135
136                 ptr_size = file_data.size;
137                 ptr_size -=
138                     ((unsigned char *) ptr -
139                                     (unsigned char *) file_data.data);
140
141                 if (ptr_size < 0)
142                         break;
143
144         }
145
146         gnutls_free(file_data.data);
147         fprintf(stderr, "Loaded %d private keys.\n", (int) *privkey_size);
148
149         return key;
150 }