15fff9558SSimon J. Gerraty /* 25fff9558SSimon J. Gerraty * Copyright (c) 2017-2018, Juniper Networks, Inc. 35fff9558SSimon J. Gerraty * 45fff9558SSimon J. Gerraty * Redistribution and use in source and binary forms, with or without 55fff9558SSimon J. Gerraty * modification, are permitted provided that the following conditions 65fff9558SSimon J. Gerraty * are met: 75fff9558SSimon J. Gerraty * 1. Redistributions of source code must retain the above copyright 85fff9558SSimon J. Gerraty * notice, this list of conditions and the following disclaimer. 95fff9558SSimon J. Gerraty * 2. Redistributions in binary form must reproduce the above copyright 105fff9558SSimon J. Gerraty * notice, this list of conditions and the following disclaimer in the 115fff9558SSimon J. Gerraty * documentation and/or other materials provided with the distribution. 125fff9558SSimon J. Gerraty * 135fff9558SSimon J. Gerraty * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 145fff9558SSimon J. Gerraty * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 155fff9558SSimon J. Gerraty * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 165fff9558SSimon J. Gerraty * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 175fff9558SSimon J. Gerraty * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 185fff9558SSimon J. Gerraty * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 195fff9558SSimon J. Gerraty * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 205fff9558SSimon J. Gerraty * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 215fff9558SSimon J. Gerraty * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 225fff9558SSimon J. Gerraty * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 235fff9558SSimon J. Gerraty * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 245fff9558SSimon J. Gerraty */ 255fff9558SSimon J. Gerraty #include <sys/cdefs.h> 265fff9558SSimon J. Gerraty __FBSDID("$FreeBSD$"); 275fff9558SSimon J. Gerraty 285fff9558SSimon J. Gerraty #include "../libsecureboot-priv.h" 295fff9558SSimon J. Gerraty 305fff9558SSimon J. Gerraty #include <unistd.h> 315fff9558SSimon J. Gerraty #include <err.h> 325fff9558SSimon J. Gerraty #include <verify_file.h> 335fff9558SSimon J. Gerraty 34*66655411SSimon J. Gerraty /* keep clang quiet */ 35*66655411SSimon J. Gerraty extern char *Destdir; 36*66655411SSimon J. Gerraty extern size_t DestdirLen; 37*66655411SSimon J. Gerraty extern char *Skip; 38*66655411SSimon J. Gerraty extern time_t ve_utc; 39*66655411SSimon J. Gerraty 40afc571b1SSimon J. Gerraty size_t DestdirLen; 41afc571b1SSimon J. Gerraty char *Destdir; 425fff9558SSimon J. Gerraty char *Skip; 435fff9558SSimon J. Gerraty 445fff9558SSimon J. Gerraty int 455fff9558SSimon J. Gerraty main(int argc, char *argv[]) 465fff9558SSimon J. Gerraty { 475fff9558SSimon J. Gerraty int n; 485fff9558SSimon J. Gerraty int fd; 495fff9558SSimon J. Gerraty int c; 505fff9558SSimon J. Gerraty int Vflag; 51*66655411SSimon J. Gerraty int vflag; 525fff9558SSimon J. Gerraty char *cp; 535fff9558SSimon J. Gerraty char *prefix; 545fff9558SSimon J. Gerraty 55afc571b1SSimon J. Gerraty Destdir = NULL; 56afc571b1SSimon J. Gerraty DestdirLen = 0; 575fff9558SSimon J. Gerraty prefix = NULL; 585fff9558SSimon J. Gerraty Skip = NULL; 595fff9558SSimon J. Gerraty 605fff9558SSimon J. Gerraty n = ve_trust_init(); 615fff9558SSimon J. Gerraty Vflag = 0; 62*66655411SSimon J. Gerraty vflag = 0; 635fff9558SSimon J. Gerraty 64*66655411SSimon J. Gerraty while ((c = getopt(argc, argv, "D:dp:s:T:u:Vv")) != -1) { 655fff9558SSimon J. Gerraty switch (c) { 66afc571b1SSimon J. Gerraty case 'D': 67afc571b1SSimon J. Gerraty Destdir = optarg; 68afc571b1SSimon J. Gerraty DestdirLen = strlen(optarg); 69afc571b1SSimon J. Gerraty break; 705fff9558SSimon J. Gerraty case 'd': 715fff9558SSimon J. Gerraty DebugVe++; 725fff9558SSimon J. Gerraty break; 735fff9558SSimon J. Gerraty case 'p': 745fff9558SSimon J. Gerraty prefix = optarg; 755fff9558SSimon J. Gerraty break; 765fff9558SSimon J. Gerraty case 's': 775fff9558SSimon J. Gerraty Skip = optarg; 785fff9558SSimon J. Gerraty break; 795fff9558SSimon J. Gerraty case 'T': 805fff9558SSimon J. Gerraty n = ve_trust_add(optarg); 815fff9558SSimon J. Gerraty printf("Local trust %s: %d\n", optarg, n); 825fff9558SSimon J. Gerraty break; 835fff9558SSimon J. Gerraty case 'V': 845fff9558SSimon J. Gerraty Vflag = 1; 855fff9558SSimon J. Gerraty break; 86*66655411SSimon J. Gerraty case 'v': 87*66655411SSimon J. Gerraty vflag = 1; 88*66655411SSimon J. Gerraty break; 89*66655411SSimon J. Gerraty case 'u': 90*66655411SSimon J. Gerraty ve_utc = (time_t)atoi(optarg); 91*66655411SSimon J. Gerraty break; 925fff9558SSimon J. Gerraty default: 935fff9558SSimon J. Gerraty errx(1, "unknown option: -%c", c); 945fff9558SSimon J. Gerraty break; 955fff9558SSimon J. Gerraty } 965fff9558SSimon J. Gerraty } 975fff9558SSimon J. Gerraty 98*66655411SSimon J. Gerraty if (!vflag) { 99*66655411SSimon J. Gerraty printf("Trust %d\n", n); 100980bde58SSimon J. Gerraty #ifdef VE_PCR_SUPPORT 101980bde58SSimon J. Gerraty ve_pcr_updating_set(1); 102980bde58SSimon J. Gerraty #endif 1035fff9558SSimon J. Gerraty ve_self_tests(); 104*66655411SSimon J. Gerraty } 1055fff9558SSimon J. Gerraty for ( ; optind < argc; optind++) { 1065fff9558SSimon J. Gerraty if (Vflag) { 1075fff9558SSimon J. Gerraty /* 1085fff9558SSimon J. Gerraty * Simulate what loader does. 1095fff9558SSimon J. Gerraty * verify_file should "just work" 1105fff9558SSimon J. Gerraty */ 1115fff9558SSimon J. Gerraty fd = open(argv[optind], O_RDONLY); 1125fff9558SSimon J. Gerraty if (fd > 0) { 1135fff9558SSimon J. Gerraty /* 1145fff9558SSimon J. Gerraty * See if verify_file is happy 1155fff9558SSimon J. Gerraty */ 1165fff9558SSimon J. Gerraty int x; 1175fff9558SSimon J. Gerraty 118afc571b1SSimon J. Gerraty x = verify_file(fd, argv[optind], 0, VE_GUESS, __func__); 1195fff9558SSimon J. Gerraty printf("verify_file(%s) = %d\n", argv[optind], x); 1205fff9558SSimon J. Gerraty close(fd); 1215fff9558SSimon J. Gerraty } 1225fff9558SSimon J. Gerraty continue; 1235fff9558SSimon J. Gerraty } 1245fff9558SSimon J. Gerraty #ifdef VE_OPENPGP_SUPPORT 1255fff9558SSimon J. Gerraty if (strstr(argv[optind], "asc")) { 1265fff9558SSimon J. Gerraty cp = (char *)verify_asc(argv[optind], 1); 1275fff9558SSimon J. Gerraty if (cp) { 1285fff9558SSimon J. Gerraty printf("Verified: %s: %.28s...\n", 1295fff9558SSimon J. Gerraty argv[optind], cp); 130*66655411SSimon J. Gerraty if (!vflag) 1315fff9558SSimon J. Gerraty fingerprint_info_add(argv[optind], 1325fff9558SSimon J. Gerraty prefix, Skip, cp, NULL); 1335fff9558SSimon J. Gerraty } else { 1345fff9558SSimon J. Gerraty fprintf(stderr, "%s: %s\n", 1355fff9558SSimon J. Gerraty argv[optind], ve_error_get()); 1365fff9558SSimon J. Gerraty } 1375fff9558SSimon J. Gerraty } else 1385fff9558SSimon J. Gerraty #endif 1395fff9558SSimon J. Gerraty if (strstr(argv[optind], "sig")) { 1405fff9558SSimon J. Gerraty cp = (char *)verify_sig(argv[optind], 1); 1415fff9558SSimon J. Gerraty if (cp) { 1425fff9558SSimon J. Gerraty printf("Verified: %s: %.28s...\n", 1435fff9558SSimon J. Gerraty argv[optind], cp); 144*66655411SSimon J. Gerraty if (!vflag) 1455fff9558SSimon J. Gerraty fingerprint_info_add(argv[optind], 1465fff9558SSimon J. Gerraty prefix, Skip, cp, NULL); 1475fff9558SSimon J. Gerraty } else { 1485fff9558SSimon J. Gerraty fprintf(stderr, "%s: %s\n", 1495fff9558SSimon J. Gerraty argv[optind], ve_error_get()); 1505fff9558SSimon J. Gerraty } 1515fff9558SSimon J. Gerraty } else if (strstr(argv[optind], "manifest")) { 1525fff9558SSimon J. Gerraty cp = (char *)read_file(argv[optind], NULL); 1535fff9558SSimon J. Gerraty if (cp) { 1545fff9558SSimon J. Gerraty fingerprint_info_add(argv[optind], 1555fff9558SSimon J. Gerraty prefix, Skip, cp, NULL); 1565fff9558SSimon J. Gerraty } 1575fff9558SSimon J. Gerraty } else { 1585fff9558SSimon J. Gerraty fd = verify_open(argv[optind], O_RDONLY); 1595fff9558SSimon J. Gerraty printf("verify_open(%s) = %d %s\n", argv[optind], fd, 1605fff9558SSimon J. Gerraty (fd < 0) ? ve_error_get() : ""); 1615fff9558SSimon J. Gerraty if (fd > 0) { 1625fff9558SSimon J. Gerraty /* 1635fff9558SSimon J. Gerraty * Check that vectx_* can also verify the file. 1645fff9558SSimon J. Gerraty */ 1655fff9558SSimon J. Gerraty void *vp; 1665fff9558SSimon J. Gerraty char buf[BUFSIZ]; 1675fff9558SSimon J. Gerraty struct stat st; 1685fff9558SSimon J. Gerraty int error; 169*66655411SSimon J. Gerraty off_t off; 170*66655411SSimon J. Gerraty size_t nb; 1715fff9558SSimon J. Gerraty 1725fff9558SSimon J. Gerraty fstat(fd, &st); 1735fff9558SSimon J. Gerraty lseek(fd, 0, SEEK_SET); 1745fff9558SSimon J. Gerraty off = st.st_size % 512; 1755fff9558SSimon J. Gerraty vp = vectx_open(fd, argv[optind], off, 176afc571b1SSimon J. Gerraty &st, &error, __func__); 1775fff9558SSimon J. Gerraty if (!vp) { 1785fff9558SSimon J. Gerraty printf("vectx_open(%s) failed: %d %s\n", 1795fff9558SSimon J. Gerraty argv[optind], error, 1805fff9558SSimon J. Gerraty ve_error_get()); 1815fff9558SSimon J. Gerraty } else { 1825fff9558SSimon J. Gerraty off = vectx_lseek(vp, 1835fff9558SSimon J. Gerraty (st.st_size % 1024), SEEK_SET); 184afc571b1SSimon J. Gerraty /* we can seek backwards! */ 185afc571b1SSimon J. Gerraty off = vectx_lseek(vp, off/2, SEEK_SET); 1865fff9558SSimon J. Gerraty if (off < st.st_size) { 187*66655411SSimon J. Gerraty nb = vectx_read(vp, buf, 1885fff9558SSimon J. Gerraty sizeof(buf)); 189*66655411SSimon J. Gerraty if (nb > 0) 190*66655411SSimon J. Gerraty off += nb; 1915fff9558SSimon J. Gerraty } 1925fff9558SSimon J. Gerraty off = vectx_lseek(vp, 0, SEEK_END); 1935fff9558SSimon J. Gerraty /* repeating that should be harmless */ 1945fff9558SSimon J. Gerraty off = vectx_lseek(vp, 0, SEEK_END); 195afc571b1SSimon J. Gerraty error = vectx_close(vp, VE_MUST, __func__); 1965fff9558SSimon J. Gerraty if (error) { 1975fff9558SSimon J. Gerraty printf("vectx_close(%s) == %d %s\n", 1985fff9558SSimon J. Gerraty argv[optind], error, 1995fff9558SSimon J. Gerraty ve_error_get()); 2005fff9558SSimon J. Gerraty } else { 2015fff9558SSimon J. Gerraty printf("vectx_close: Verified: %s\n", 2025fff9558SSimon J. Gerraty argv[optind]); 2035fff9558SSimon J. Gerraty } 2045fff9558SSimon J. Gerraty } 2055fff9558SSimon J. Gerraty close(fd); 2065fff9558SSimon J. Gerraty } 2075fff9558SSimon J. Gerraty } 2085fff9558SSimon J. Gerraty } 209980bde58SSimon J. Gerraty #ifdef VE_PCR_SUPPORT 210980bde58SSimon J. Gerraty verify_pcr_export(); 211980bde58SSimon J. Gerraty printf("pcr=%s\n", getenv("loader.ve.pcr")); 212980bde58SSimon J. Gerraty #endif 2135fff9558SSimon J. Gerraty return (0); 2145fff9558SSimon J. Gerraty } 2155fff9558SSimon J. Gerraty 216