1 /*
2 * Copyright (c) 2017-2018, Juniper Networks, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25 #include <sys/cdefs.h>
26 #include "../libsecureboot-priv.h"
27
28 #include <unistd.h>
29 #include <err.h>
30 #include <verify_file.h>
31
32 /* keep clang quiet */
33 extern char *Destdir;
34 extern size_t DestdirLen;
35 extern char *Skip;
36 extern time_t ve_utc;
37
38 size_t DestdirLen;
39 char *Destdir;
40 char *Skip;
41
42 int
main(int argc,char * argv[])43 main(int argc, char *argv[])
44 {
45 int n;
46 int fd;
47 int c;
48 int Vflag;
49 int vflag;
50 char *cp;
51 char *prefix;
52
53 Destdir = NULL;
54 DestdirLen = 0;
55 prefix = NULL;
56 Skip = NULL;
57
58 n = ve_trust_init();
59 Vflag = 0;
60 vflag = 0;
61
62 while ((c = getopt(argc, argv, "D:dp:s:T:u:Vv")) != -1) {
63 switch (c) {
64 case 'D':
65 Destdir = optarg;
66 DestdirLen = strlen(optarg);
67 break;
68 case 'd':
69 DebugVe++;
70 break;
71 case 'p':
72 prefix = optarg;
73 break;
74 case 's':
75 Skip = optarg;
76 break;
77 case 'T':
78 n = ve_trust_add(optarg);
79 printf("Local trust %s: %d\n", optarg, n);
80 break;
81 case 'V':
82 Vflag = 1;
83 break;
84 case 'v':
85 vflag = 1;
86 break;
87 case 'u':
88 ve_utc = (time_t)atoi(optarg);
89 break;
90 default:
91 errx(1, "unknown option: -%c", c);
92 break;
93 }
94 }
95
96 if (!vflag) {
97 printf("Trust %d\n", n);
98 #ifdef VE_PCR_SUPPORT
99 ve_pcr_updating_set(1);
100 #endif
101 ve_self_tests();
102 }
103 for ( ; optind < argc; optind++) {
104 if (Vflag) {
105 /*
106 * Simulate what loader does.
107 * verify_file should "just work"
108 */
109 fd = open(argv[optind], O_RDONLY);
110 if (fd > 0) {
111 /*
112 * See if verify_file is happy
113 */
114 int x;
115
116 x = verify_file(fd, argv[optind], 0, VE_GUESS, __func__);
117 printf("verify_file(%s) = %d\n", argv[optind], x);
118 close(fd);
119 }
120 continue;
121 }
122 #ifdef VE_OPENPGP_SUPPORT
123 if (strstr(argv[optind], "asc")) {
124 cp = (char *)verify_asc(argv[optind], 1);
125 if (cp) {
126 printf("Verified: %s: %.28s...\n",
127 argv[optind], cp);
128 if (!vflag)
129 fingerprint_info_add(argv[optind],
130 prefix, Skip, cp, NULL);
131 } else {
132 fprintf(stderr, "%s: %s\n",
133 argv[optind], ve_error_get());
134 }
135 } else
136 #endif
137 if (strstr(argv[optind], "sig")) {
138 cp = (char *)verify_sig(argv[optind], 1);
139 if (cp) {
140 printf("Verified: %s: %.28s...\n",
141 argv[optind], cp);
142 if (!vflag)
143 fingerprint_info_add(argv[optind],
144 prefix, Skip, cp, NULL);
145 } else {
146 fprintf(stderr, "%s: %s\n",
147 argv[optind], ve_error_get());
148 }
149 } else if (strstr(argv[optind], "manifest")) {
150 cp = (char *)read_file(argv[optind], NULL);
151 if (cp) {
152 fingerprint_info_add(argv[optind],
153 prefix, Skip, cp, NULL);
154 }
155 } else {
156 fd = verify_open(argv[optind], O_RDONLY);
157 printf("verify_open(%s) = %d %s\n", argv[optind], fd,
158 (fd < 0) ? ve_error_get() : "");
159 if (fd > 0) {
160 /*
161 * Check that vectx_* can also verify the file.
162 */
163 void *vp;
164 char buf[BUFSIZ];
165 struct stat st;
166 int error;
167 off_t off;
168 size_t nb;
169
170 fstat(fd, &st);
171 lseek(fd, 0, SEEK_SET);
172 off = st.st_size % 512;
173 vp = vectx_open(fd, argv[optind], off,
174 &st, &error, __func__);
175 if (!vp) {
176 printf("vectx_open(%s) failed: %d %s\n",
177 argv[optind], error,
178 ve_error_get());
179 } else {
180 off = vectx_lseek(vp,
181 (st.st_size % 1024), SEEK_SET);
182 /* we can seek backwards! */
183 off = vectx_lseek(vp, off/2, SEEK_SET);
184 if (off < st.st_size) {
185 nb = vectx_read(vp, buf,
186 sizeof(buf));
187 if (nb > 0)
188 off += nb;
189 }
190 off = vectx_lseek(vp, 0, SEEK_END);
191 /* repeating that should be harmless */
192 off = vectx_lseek(vp, 0, SEEK_END);
193 error = vectx_close(vp, VE_MUST, __func__);
194 if (error) {
195 printf("vectx_close(%s) == %d %s\n",
196 argv[optind], error,
197 ve_error_get());
198 } else {
199 printf("vectx_close: Verified: %s\n",
200 argv[optind]);
201 }
202 }
203 close(fd);
204 }
205 }
206 }
207 #ifdef VE_PCR_SUPPORT
208 verify_pcr_export();
209 printf("pcr=%s\n", getenv("loader.ve.pcr"));
210 #endif
211 return (0);
212 }
213
214