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 #include "../libsecureboot-priv.h"
275fff9558SSimon J. Gerraty
285fff9558SSimon J. Gerraty #include <unistd.h>
295fff9558SSimon J. Gerraty #include <err.h>
305fff9558SSimon J. Gerraty #include <verify_file.h>
315fff9558SSimon J. Gerraty
32*66655411SSimon J. Gerraty /* keep clang quiet */
33*66655411SSimon J. Gerraty extern char *Destdir;
34*66655411SSimon J. Gerraty extern size_t DestdirLen;
35*66655411SSimon J. Gerraty extern char *Skip;
36*66655411SSimon J. Gerraty extern time_t ve_utc;
37*66655411SSimon J. Gerraty
38afc571b1SSimon J. Gerraty size_t DestdirLen;
39afc571b1SSimon J. Gerraty char *Destdir;
405fff9558SSimon J. Gerraty char *Skip;
415fff9558SSimon J. Gerraty
425fff9558SSimon J. Gerraty int
main(int argc,char * argv[])435fff9558SSimon J. Gerraty main(int argc, char *argv[])
445fff9558SSimon J. Gerraty {
455fff9558SSimon J. Gerraty int n;
465fff9558SSimon J. Gerraty int fd;
475fff9558SSimon J. Gerraty int c;
485fff9558SSimon J. Gerraty int Vflag;
49*66655411SSimon J. Gerraty int vflag;
505fff9558SSimon J. Gerraty char *cp;
515fff9558SSimon J. Gerraty char *prefix;
525fff9558SSimon J. Gerraty
53afc571b1SSimon J. Gerraty Destdir = NULL;
54afc571b1SSimon J. Gerraty DestdirLen = 0;
555fff9558SSimon J. Gerraty prefix = NULL;
565fff9558SSimon J. Gerraty Skip = NULL;
575fff9558SSimon J. Gerraty
585fff9558SSimon J. Gerraty n = ve_trust_init();
595fff9558SSimon J. Gerraty Vflag = 0;
60*66655411SSimon J. Gerraty vflag = 0;
615fff9558SSimon J. Gerraty
62*66655411SSimon J. Gerraty while ((c = getopt(argc, argv, "D:dp:s:T:u:Vv")) != -1) {
635fff9558SSimon J. Gerraty switch (c) {
64afc571b1SSimon J. Gerraty case 'D':
65afc571b1SSimon J. Gerraty Destdir = optarg;
66afc571b1SSimon J. Gerraty DestdirLen = strlen(optarg);
67afc571b1SSimon J. Gerraty break;
685fff9558SSimon J. Gerraty case 'd':
695fff9558SSimon J. Gerraty DebugVe++;
705fff9558SSimon J. Gerraty break;
715fff9558SSimon J. Gerraty case 'p':
725fff9558SSimon J. Gerraty prefix = optarg;
735fff9558SSimon J. Gerraty break;
745fff9558SSimon J. Gerraty case 's':
755fff9558SSimon J. Gerraty Skip = optarg;
765fff9558SSimon J. Gerraty break;
775fff9558SSimon J. Gerraty case 'T':
785fff9558SSimon J. Gerraty n = ve_trust_add(optarg);
795fff9558SSimon J. Gerraty printf("Local trust %s: %d\n", optarg, n);
805fff9558SSimon J. Gerraty break;
815fff9558SSimon J. Gerraty case 'V':
825fff9558SSimon J. Gerraty Vflag = 1;
835fff9558SSimon J. Gerraty break;
84*66655411SSimon J. Gerraty case 'v':
85*66655411SSimon J. Gerraty vflag = 1;
86*66655411SSimon J. Gerraty break;
87*66655411SSimon J. Gerraty case 'u':
88*66655411SSimon J. Gerraty ve_utc = (time_t)atoi(optarg);
89*66655411SSimon J. Gerraty break;
905fff9558SSimon J. Gerraty default:
915fff9558SSimon J. Gerraty errx(1, "unknown option: -%c", c);
925fff9558SSimon J. Gerraty break;
935fff9558SSimon J. Gerraty }
945fff9558SSimon J. Gerraty }
955fff9558SSimon J. Gerraty
96*66655411SSimon J. Gerraty if (!vflag) {
97*66655411SSimon J. Gerraty printf("Trust %d\n", n);
98980bde58SSimon J. Gerraty #ifdef VE_PCR_SUPPORT
99980bde58SSimon J. Gerraty ve_pcr_updating_set(1);
100980bde58SSimon J. Gerraty #endif
1015fff9558SSimon J. Gerraty ve_self_tests();
102*66655411SSimon J. Gerraty }
1035fff9558SSimon J. Gerraty for ( ; optind < argc; optind++) {
1045fff9558SSimon J. Gerraty if (Vflag) {
1055fff9558SSimon J. Gerraty /*
1065fff9558SSimon J. Gerraty * Simulate what loader does.
1075fff9558SSimon J. Gerraty * verify_file should "just work"
1085fff9558SSimon J. Gerraty */
1095fff9558SSimon J. Gerraty fd = open(argv[optind], O_RDONLY);
1105fff9558SSimon J. Gerraty if (fd > 0) {
1115fff9558SSimon J. Gerraty /*
1125fff9558SSimon J. Gerraty * See if verify_file is happy
1135fff9558SSimon J. Gerraty */
1145fff9558SSimon J. Gerraty int x;
1155fff9558SSimon J. Gerraty
116afc571b1SSimon J. Gerraty x = verify_file(fd, argv[optind], 0, VE_GUESS, __func__);
1175fff9558SSimon J. Gerraty printf("verify_file(%s) = %d\n", argv[optind], x);
1185fff9558SSimon J. Gerraty close(fd);
1195fff9558SSimon J. Gerraty }
1205fff9558SSimon J. Gerraty continue;
1215fff9558SSimon J. Gerraty }
1225fff9558SSimon J. Gerraty #ifdef VE_OPENPGP_SUPPORT
1235fff9558SSimon J. Gerraty if (strstr(argv[optind], "asc")) {
1245fff9558SSimon J. Gerraty cp = (char *)verify_asc(argv[optind], 1);
1255fff9558SSimon J. Gerraty if (cp) {
1265fff9558SSimon J. Gerraty printf("Verified: %s: %.28s...\n",
1275fff9558SSimon J. Gerraty argv[optind], cp);
128*66655411SSimon J. Gerraty if (!vflag)
1295fff9558SSimon J. Gerraty fingerprint_info_add(argv[optind],
1305fff9558SSimon J. Gerraty prefix, Skip, cp, NULL);
1315fff9558SSimon J. Gerraty } else {
1325fff9558SSimon J. Gerraty fprintf(stderr, "%s: %s\n",
1335fff9558SSimon J. Gerraty argv[optind], ve_error_get());
1345fff9558SSimon J. Gerraty }
1355fff9558SSimon J. Gerraty } else
1365fff9558SSimon J. Gerraty #endif
1375fff9558SSimon J. Gerraty if (strstr(argv[optind], "sig")) {
1385fff9558SSimon J. Gerraty cp = (char *)verify_sig(argv[optind], 1);
1395fff9558SSimon J. Gerraty if (cp) {
1405fff9558SSimon J. Gerraty printf("Verified: %s: %.28s...\n",
1415fff9558SSimon J. Gerraty argv[optind], cp);
142*66655411SSimon J. Gerraty if (!vflag)
1435fff9558SSimon J. Gerraty fingerprint_info_add(argv[optind],
1445fff9558SSimon J. Gerraty prefix, Skip, cp, NULL);
1455fff9558SSimon J. Gerraty } else {
1465fff9558SSimon J. Gerraty fprintf(stderr, "%s: %s\n",
1475fff9558SSimon J. Gerraty argv[optind], ve_error_get());
1485fff9558SSimon J. Gerraty }
1495fff9558SSimon J. Gerraty } else if (strstr(argv[optind], "manifest")) {
1505fff9558SSimon J. Gerraty cp = (char *)read_file(argv[optind], NULL);
1515fff9558SSimon J. Gerraty if (cp) {
1525fff9558SSimon J. Gerraty fingerprint_info_add(argv[optind],
1535fff9558SSimon J. Gerraty prefix, Skip, cp, NULL);
1545fff9558SSimon J. Gerraty }
1555fff9558SSimon J. Gerraty } else {
1565fff9558SSimon J. Gerraty fd = verify_open(argv[optind], O_RDONLY);
1575fff9558SSimon J. Gerraty printf("verify_open(%s) = %d %s\n", argv[optind], fd,
1585fff9558SSimon J. Gerraty (fd < 0) ? ve_error_get() : "");
1595fff9558SSimon J. Gerraty if (fd > 0) {
1605fff9558SSimon J. Gerraty /*
1615fff9558SSimon J. Gerraty * Check that vectx_* can also verify the file.
1625fff9558SSimon J. Gerraty */
1635fff9558SSimon J. Gerraty void *vp;
1645fff9558SSimon J. Gerraty char buf[BUFSIZ];
1655fff9558SSimon J. Gerraty struct stat st;
1665fff9558SSimon J. Gerraty int error;
167*66655411SSimon J. Gerraty off_t off;
168*66655411SSimon J. Gerraty size_t nb;
1695fff9558SSimon J. Gerraty
1705fff9558SSimon J. Gerraty fstat(fd, &st);
1715fff9558SSimon J. Gerraty lseek(fd, 0, SEEK_SET);
1725fff9558SSimon J. Gerraty off = st.st_size % 512;
1735fff9558SSimon J. Gerraty vp = vectx_open(fd, argv[optind], off,
174afc571b1SSimon J. Gerraty &st, &error, __func__);
1755fff9558SSimon J. Gerraty if (!vp) {
1765fff9558SSimon J. Gerraty printf("vectx_open(%s) failed: %d %s\n",
1775fff9558SSimon J. Gerraty argv[optind], error,
1785fff9558SSimon J. Gerraty ve_error_get());
1795fff9558SSimon J. Gerraty } else {
1805fff9558SSimon J. Gerraty off = vectx_lseek(vp,
1815fff9558SSimon J. Gerraty (st.st_size % 1024), SEEK_SET);
182afc571b1SSimon J. Gerraty /* we can seek backwards! */
183afc571b1SSimon J. Gerraty off = vectx_lseek(vp, off/2, SEEK_SET);
1845fff9558SSimon J. Gerraty if (off < st.st_size) {
185*66655411SSimon J. Gerraty nb = vectx_read(vp, buf,
1865fff9558SSimon J. Gerraty sizeof(buf));
187*66655411SSimon J. Gerraty if (nb > 0)
188*66655411SSimon J. Gerraty off += nb;
1895fff9558SSimon J. Gerraty }
1905fff9558SSimon J. Gerraty off = vectx_lseek(vp, 0, SEEK_END);
1915fff9558SSimon J. Gerraty /* repeating that should be harmless */
1925fff9558SSimon J. Gerraty off = vectx_lseek(vp, 0, SEEK_END);
193afc571b1SSimon J. Gerraty error = vectx_close(vp, VE_MUST, __func__);
1945fff9558SSimon J. Gerraty if (error) {
1955fff9558SSimon J. Gerraty printf("vectx_close(%s) == %d %s\n",
1965fff9558SSimon J. Gerraty argv[optind], error,
1975fff9558SSimon J. Gerraty ve_error_get());
1985fff9558SSimon J. Gerraty } else {
1995fff9558SSimon J. Gerraty printf("vectx_close: Verified: %s\n",
2005fff9558SSimon J. Gerraty argv[optind]);
2015fff9558SSimon J. Gerraty }
2025fff9558SSimon J. Gerraty }
2035fff9558SSimon J. Gerraty close(fd);
2045fff9558SSimon J. Gerraty }
2055fff9558SSimon J. Gerraty }
2065fff9558SSimon J. Gerraty }
207980bde58SSimon J. Gerraty #ifdef VE_PCR_SUPPORT
208980bde58SSimon J. Gerraty verify_pcr_export();
209980bde58SSimon J. Gerraty printf("pcr=%s\n", getenv("loader.ve.pcr"));
210980bde58SSimon J. Gerraty #endif
2115fff9558SSimon J. Gerraty return (0);
2125fff9558SSimon J. Gerraty }
2135fff9558SSimon J. Gerraty
214