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 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