xref: /freebsd/lib/libsecureboot/tests/tvo.c (revision 10ff414c)
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 __FBSDID("$FreeBSD$");
27 
28 #include "../libsecureboot-priv.h"
29 
30 #include <unistd.h>
31 #include <err.h>
32 #include <verify_file.h>
33 
34 size_t DestdirLen;
35 char *Destdir;
36 char *Skip;
37 
38 int
39 main(int argc, char *argv[])
40 {
41 	int n;
42 	int fd;
43 	int c;
44 	int Vflag;
45 	char *cp;
46 	char *prefix;
47 	char *destdir;
48 
49 	Destdir = NULL;
50 	DestdirLen = 0;
51 	prefix = NULL;
52 	Skip = NULL;
53 
54 	n = ve_trust_init();
55 	printf("Trust %d\n", n);
56 	Vflag = 0;
57 
58 	while ((c = getopt(argc, argv, "D:dp:s:T:V")) != -1) {
59 		switch (c) {
60 		case 'D':
61 			Destdir = optarg;
62 			DestdirLen = strlen(optarg);
63 			break;
64 		case 'd':
65 			DebugVe++;
66 			break;
67 		case 'p':
68 			prefix = optarg;
69 			break;
70 		case 's':
71 			Skip = optarg;
72 			break;
73 		case 'T':
74 			n = ve_trust_add(optarg);
75 			printf("Local trust %s: %d\n", optarg, n);
76 			break;
77 		case 'V':
78 			Vflag = 1;
79 			break;
80 		default:
81 			errx(1, "unknown option: -%c", c);
82 			break;
83 		}
84 	}
85 
86 #ifdef VE_PCR_SUPPORT
87 	ve_pcr_updating_set(1);
88 #endif
89 	ve_self_tests();
90 
91 	for ( ; optind < argc; optind++) {
92 		if (Vflag) {
93 			/*
94 			 * Simulate what loader does.
95 			 * verify_file should "just work"
96 			 */
97 			fd = open(argv[optind], O_RDONLY);
98 			if (fd > 0) {
99 				/*
100 				 * See if verify_file is happy
101 				 */
102 				int x;
103 
104 				x = verify_file(fd, argv[optind], 0, VE_GUESS, __func__);
105 				printf("verify_file(%s) = %d\n", argv[optind], x);
106 				close(fd);
107 			}
108 			continue;
109 		}
110 #ifdef VE_OPENPGP_SUPPORT
111 		if (strstr(argv[optind], "asc")) {
112 			cp = (char *)verify_asc(argv[optind], 1);
113 			if (cp) {
114 				printf("Verified: %s: %.28s...\n",
115 				    argv[optind], cp);
116 				fingerprint_info_add(argv[optind],
117 				    prefix, Skip, cp, NULL);
118 			} else {
119 				fprintf(stderr, "%s: %s\n",
120 				    argv[optind], ve_error_get());
121 			}
122 		} else
123 #endif
124 		if (strstr(argv[optind], "sig")) {
125 			cp = (char *)verify_sig(argv[optind], 1);
126 			if (cp) {
127 				printf("Verified: %s: %.28s...\n",
128 				    argv[optind], cp);
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 if (strstr(argv[optind], "manifest")) {
136 			cp = (char *)read_file(argv[optind], NULL);
137 			if (cp) {
138 				fingerprint_info_add(argv[optind],
139 				    prefix, Skip, cp, NULL);
140 			}
141 		} else {
142 			fd = verify_open(argv[optind], O_RDONLY);
143 			printf("verify_open(%s) = %d %s\n", argv[optind], fd,
144 			    (fd < 0) ? ve_error_get() : "");
145 			if (fd > 0) {
146 				/*
147 				 * Check that vectx_* can also verify the file.
148 				 */
149 				void *vp;
150 				char buf[BUFSIZ];
151 				struct stat st;
152 				int error;
153 				size_t off, n;
154 
155 				fstat(fd, &st);
156 				lseek(fd, 0, SEEK_SET);
157 				off = st.st_size % 512;
158 				vp = vectx_open(fd, argv[optind], off,
159 				    &st, &error, __func__);
160 				if (!vp) {
161 					printf("vectx_open(%s) failed: %d %s\n",
162 					    argv[optind], error,
163 					    ve_error_get());
164 				} else {
165 					off = vectx_lseek(vp,
166 					    (st.st_size % 1024), SEEK_SET);
167 					/* we can seek backwards! */
168 					off = vectx_lseek(vp, off/2, SEEK_SET);
169 					if (off < st.st_size) {
170 						n = vectx_read(vp, buf,
171 						    sizeof(buf));
172 						if (n > 0)
173 							off += n;
174 					}
175 					off = vectx_lseek(vp, 0, SEEK_END);
176 					/* repeating that should be harmless */
177 					off = vectx_lseek(vp, 0, SEEK_END);
178 					error = vectx_close(vp, VE_MUST, __func__);
179 					if (error) {
180 						printf("vectx_close(%s) == %d %s\n",
181 						    argv[optind], error,
182 						    ve_error_get());
183 					} else {
184 						printf("vectx_close: Verified: %s\n",
185 						    argv[optind]);
186 					}
187 				}
188 				close(fd);
189 			}
190 		}
191 	}
192 #ifdef VE_PCR_SUPPORT
193 	verify_pcr_export();
194 	printf("pcr=%s\n", getenv("loader.ve.pcr"));
195 #endif
196 	return (0);
197 }
198 
199