]> git.cameronkatri.com Git - trustcache.git/blob - create.c
Add support for new version 2 trustcaches
[trustcache.git] / create.c
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2022 Cameron Katri. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY CAMERON KATRI AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL CAMERON KATRI OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <errno.h>
29 #include <getopt.h>
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 #include "trustcache.h"
37 #include "uuid/uuid.h"
38
39 int
40 tccreate(int argc, char **argv)
41 {
42 struct trust_cache cache = {
43 .version = 1,
44 .uuid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
45 .num_entries = 0,
46 .entries = NULL,
47 }, append = {};
48
49 uuid_generate(cache.uuid);
50
51 int ch;
52 while ((ch = getopt(argc, argv, "u:v:")) != -1) {
53 switch (ch) {
54 case 'u':
55 if (uuid_parse(optarg, cache.uuid) != 0)
56 fprintf(stderr, "Failed to parse %s as a UUID\n", optarg);
57 break;
58 case 'v':
59 if (strlen(optarg) != 1 || (optarg[0] != '0' && optarg[0] != '1' && optarg[0] != '2')) {
60 fprintf(stderr, "Unsupported trustcache version %s\n", optarg);
61 return 1;
62 }
63 if (optarg[0] == '0')
64 cache.version = 0;
65 else if (optarg[0] == '1')
66 cache.version = 1;
67 else if (optarg[0] == '2')
68 cache.version = 2;
69 break;
70 }
71 }
72
73 argc -= optind;
74 argv += optind;
75
76 if (argc == 0)
77 return -1;
78
79 for (int i = 1; i < argc; i++) {
80 append = cache_from_tree(argv[i], cache.version);
81 if (append.version == 0) {
82 if ((cache.hashes = realloc(cache.hashes, sizeof(trust_cache_hash0) *
83 (cache.num_entries + append.num_entries))) == NULL)
84 exit(1);
85 for (uint32_t j = 0; j < append.num_entries; j++) {
86 memcpy(cache.hashes[cache.num_entries + j], append.hashes[j], CS_CDHASH_LEN);
87 }
88 } else if (append.version == 1) {
89 if ((cache.entries = realloc(cache.entries, sizeof(struct trust_cache_entry1) *
90 (cache.num_entries + append.num_entries))) == NULL)
91 exit(1);
92 for (uint32_t j = 0; j < append.num_entries; j++) {
93 cache.entries[cache.num_entries + j].hash_type = append.entries[j].hash_type;
94 cache.entries[cache.num_entries + j].flags = append.entries[j].flags;
95 memcpy(cache.entries[cache.num_entries + j].cdhash, append.entries[j].cdhash, CS_CDHASH_LEN);
96 }
97 } else if (append.version == 2) {
98 if ((cache.entries2 = realloc(cache.entries2, sizeof(struct trust_cache_entry2) *
99 (cache.num_entries + append.num_entries))) == NULL)
100 exit(1);
101 for (uint32_t j = 0; j < append.num_entries; j++) {
102 cache.entries2[cache.num_entries + j].hash_type = append.entries2[j].hash_type;
103 cache.entries2[cache.num_entries + j].flags = append.entries2[j].flags;
104 cache.entries2[cache.num_entries + j].category = append.entries2[j].category;
105 memcpy(cache.entries2[cache.num_entries + j].cdhash, append.entries2[j].cdhash, CS_CDHASH_LEN);
106 }
107 }
108 free(append.hashes);
109 cache.num_entries += append.num_entries;
110 }
111
112 if (cache.version == 0)
113 qsort(cache.hashes, cache.num_entries, sizeof(*cache.hashes), hash_cmp);
114 else if (cache.version == 1)
115 qsort(cache.entries, cache.num_entries, sizeof(*cache.entries), ent_cmp);
116 else if (cache.version == 2)
117 qsort(cache.entries, cache.num_entries, sizeof(*cache.entries2), ent_cmp);
118
119 if (writetrustcache(cache, argv[0]) == -1)
120 return 1;
121
122 free(cache.entries);
123
124 return 0;
125 }