xref: /freebsd/lib/libsecureboot/tests/tvo.c (revision 148a8da8)
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 	ve_self_tests();
78 
79 	for ( ; optind < argc; optind++) {
80 		if (Vflag) {
81 			/*
82 			 * Simulate what loader does.
83 			 * verify_file should "just work"
84 			 */
85 			fd = open(argv[optind], O_RDONLY);
86 			if (fd > 0) {
87 				/*
88 				 * See if verify_file is happy
89 				 */
90 				int x;
91 
92 				x = verify_file(fd, argv[optind], 0, VE_GUESS);
93 				printf("verify_file(%s) = %d\n", argv[optind], x);
94 				close(fd);
95 			}
96 			continue;
97 		}
98 #ifdef VE_OPENPGP_SUPPORT
99 		if (strstr(argv[optind], "asc")) {
100 			cp = (char *)verify_asc(argv[optind], 1);
101 			if (cp) {
102 				printf("Verified: %s: %.28s...\n",
103 				    argv[optind], cp);
104 				fingerprint_info_add(argv[optind],
105 				    prefix, Skip, cp, NULL);
106 			} else {
107 				fprintf(stderr, "%s: %s\n",
108 				    argv[optind], ve_error_get());
109 			}
110 		} else
111 #endif
112 		if (strstr(argv[optind], "sig")) {
113 			cp = (char *)verify_sig(argv[optind], 1);
114 			if (cp) {
115 				printf("Verified: %s: %.28s...\n",
116 				    argv[optind], cp);
117 				fingerprint_info_add(argv[optind],
118 				    prefix, Skip, cp, NULL);
119 			} else {
120 				fprintf(stderr, "%s: %s\n",
121 				    argv[optind], ve_error_get());
122 			}
123 		} else if (strstr(argv[optind], "manifest")) {
124 			cp = (char *)read_file(argv[optind], NULL);
125 			if (cp) {
126 				fingerprint_info_add(argv[optind],
127 				    prefix, Skip, cp, NULL);
128 			}
129 		} else {
130 			fd = verify_open(argv[optind], O_RDONLY);
131 			printf("verify_open(%s) = %d %s\n", argv[optind], fd,
132 			    (fd < 0) ? ve_error_get() : "");
133 			if (fd > 0) {
134 				/*
135 				 * Check that vectx_* can also verify the file.
136 				 */
137 				void *vp;
138 				char buf[BUFSIZ];
139 				struct stat st;
140 				int error;
141 				size_t off, n;
142 
143 				fstat(fd, &st);
144 				lseek(fd, 0, SEEK_SET);
145 				off = st.st_size % 512;
146 				vp = vectx_open(fd, argv[optind], off,
147 				    &st, &error);
148 				if (!vp) {
149 					printf("vectx_open(%s) failed: %d %s\n",
150 					    argv[optind], error,
151 					    ve_error_get());
152 				} else {
153 					off = vectx_lseek(vp,
154 					    (st.st_size % 1024), SEEK_SET);
155 
156 					if (off < st.st_size) {
157 						n = vectx_read(vp, buf,
158 						    sizeof(buf));
159 						if (n > 0)
160 							off += n;
161 					}
162 					off = vectx_lseek(vp, 0, SEEK_END);
163 					/* repeating that should be harmless */
164 					off = vectx_lseek(vp, 0, SEEK_END);
165 					error = vectx_close(vp);
166 					if (error) {
167 						printf("vectx_close(%s) == %d %s\n",
168 						    argv[optind], error,
169 						    ve_error_get());
170 					} else {
171 						printf("vectx_close: Verified: %s\n",
172 						    argv[optind]);
173 					}
174 				}
175 				close(fd);
176 			}
177 		}
178 	}
179 	return (0);
180 }
181 
182