4 author: José Bollo <jose.bollo@iot.bzh>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
36 #if !defined(DEFAULT_KEY_FILE)
37 #define DEFAULT_KEY_FILE "key.pem"
39 #if !defined(DEFAULT_CERT_FILE)
40 #define DEFAULT_CERT_FILE "cert.pem"
43 const char appname[] = "wgtpkg-sign";
45 static unsigned int get_number(const char *value)
48 unsigned long int val;
50 val = strtoul(value, &end, 10);
51 if (*end || 0 == val || val >= UINT_MAX || *value == '-') {
52 ERROR("bad number value %s", value);
55 return (unsigned int)val;
61 "usage: %s [-f] [-k keyfile] [-c certfile]... [-d number | -a] directory\n"
63 " -k keyfile the private key to use for author signing\n"
64 " -c certfile the certificate(s) to use for author signing\n"
65 " -d number the number of the distributor signature (zero for automatic)\n"
66 " -a the author signature\n"
67 " -f force overwriting\n"
75 static struct option options[] = {
76 { "key", required_argument, NULL, 'k' },
77 { "certificate", required_argument, NULL, 'c' },
78 { "distributor", required_argument, NULL, 'd' },
79 { "author", no_argument, NULL, 'a' },
80 { "force", no_argument, NULL, 'f' },
81 { "help", no_argument, NULL, 'h' },
82 { "quiet", no_argument, NULL, 'q' },
83 { "verbose", no_argument, NULL, 'v' },
87 /* install the widgets of the list */
88 int main(int ac, char **av)
90 int i, force, ncert, author;
92 char *keyfile, *certfiles[MAXCERT+1], *directory, **x;
97 force = ncert = author = 0;
99 keyfile = directory = NULL;
101 i = getopt_long(ac, av, "hfqvak:c:d:", options, NULL);
106 if (ncert == MAXCERT) {
107 ERROR("maximum count of certificates reached");
110 certfiles[ncert++] = optarg;
112 case 'k': x = &keyfile; break;
113 case 'd': number = get_number(optarg); continue;
114 case 'f': force = 1; continue;
115 case 'a': author = 1; continue;
116 case 'h': usage(); return 0;
125 ERROR("missing argument");
128 ERROR("unrecognized option");
132 ERROR("option set twice");
138 /* remaining arguments and final checks */
140 ERROR("no directory set");
143 directory = av[optind++];
145 ERROR("extra parameters found");
149 /* set default values */
151 keyfile = DEFAULT_KEY_FILE;
153 certfiles[ncert++] = DEFAULT_CERT_FILE;
156 if (stat(directory, &s)) {
157 ERROR("can't find directory %s", directory);
160 if (!S_ISDIR(s.st_mode)) {
161 ERROR("%s isn't a directory", directory);
164 if (access(keyfile, R_OK) != 0) {
165 ERROR("can't access private key %s", keyfile);
168 for(i = 0 ; i < ncert ; i++)
169 if (access(certfiles[i], R_OK) != 0) {
170 ERROR("can't access certificate %s", certfiles[i]);
174 /* init xmlsec module */
179 /* compute absolutes paths */
180 #define rp(x) do { char *p = realpath(x, NULL); if (p != NULL) x = p; else { ERROR("realpath failed for %s",x); return 1; } } while(0)
182 for(i = 0 ; i < ncert ; i++)
186 /* set and enter the workdir */
187 if (set_workdir(directory, 0))
195 else if (number == UINT_MAX)
196 for (number = 1; get_signature(number) != NULL ; number++);
198 if (!force && get_signature(number) != NULL) {
199 ERROR("can't overwrite existing signature %s", get_signature(number)->name);
203 NOTICE("-- SIGNING content of directory %s for number %u", directory, number);
205 certfiles[ncert] = NULL;
206 return !!create_digsig(number, keyfile, (const char**)certfiles);