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