4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
34 #if !defined(DEFAULT_KEY_FILE)
35 #define DEFAULT_KEY_FILE "key.pem"
37 #if !defined(DEFAULT_CERT_FILE)
38 #define DEFAULT_CERT_FILE "cert.pem"
41 const char appname[] = "wgtpkg-sign";
43 static unsigned int get_number(const char *value)
46 unsigned long int val;
48 val = strtoul(value, &end, 10);
49 if (*end || 0 == val || val >= UINT_MAX || *value == '-') {
50 ERROR("bad number value %s", value);
53 return (unsigned int)val;
59 "usage: %s [-f] [-k keyfile] [-c certfile]... [-d number | -a] directory\n"
61 " -k keyfile the private key to use for author signing\n"
62 " -c certfile the certificate(s) to use for author signing\n"
63 " -d number the number of the distributor signature (zero for automatic)\n"
64 " -a the author signature\n"
65 " -f force overwriting\n"
73 static struct option options[] = {
74 { "key", required_argument, NULL, 'k' },
75 { "certificate", required_argument, NULL, 'c' },
76 { "distributor", required_argument, NULL, 'd' },
77 { "author", no_argument, NULL, 'a' },
78 { "force", no_argument, NULL, 'f' },
79 { "help", no_argument, NULL, 'h' },
80 { "quiet", no_argument, NULL, 'q' },
81 { "verbose", no_argument, NULL, 'v' },
85 /* install the widgets of the list */
86 int main(int ac, char **av)
88 int i, force, ncert, author;
90 char *keyfile, *certfiles[MAXCERT+1], *directory, **x;
95 force = ncert = author = 0;
97 keyfile = directory = NULL;
99 i = getopt_long(ac, av, "hfqvak:c:d:", options, NULL);
104 if (ncert == MAXCERT) {
105 ERROR("maximum count of certificates reached");
108 certfiles[ncert++] = optarg;
110 case 'k': x = &keyfile; break;
111 case 'd': number = get_number(optarg); continue;
112 case 'f': force = 1; continue;
113 case 'a': author = 1; continue;
114 case 'h': usage(); return 0;
123 ERROR("missing argument");
126 ERROR("unrecognized option");
130 ERROR("option set twice");
136 /* remaining arguments and final checks */
138 ERROR("no directory set");
141 directory = av[optind++];
143 ERROR("extra parameters found");
147 /* set default values */
149 keyfile = DEFAULT_KEY_FILE;
151 certfiles[ncert++] = DEFAULT_CERT_FILE;
154 if (stat(directory, &s)) {
155 ERROR("can't find directory %s", directory);
158 if (!S_ISDIR(s.st_mode)) {
159 ERROR("%s isn't a directory", directory);
162 if (access(keyfile, R_OK) != 0) {
163 ERROR("can't access private key %s", keyfile);
166 for(i = 0 ; i < ncert ; i++)
167 if (access(certfiles[i], R_OK) != 0) {
168 ERROR("can't access certificate %s", certfiles[i]);
172 /* init xmlsec module */
177 /* compute absolutes paths */
178 #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)
180 for(i = 0 ; i < ncert ; i++)
184 /* set and enter the workdir */
185 if (set_workdir(directory, 0))
193 else if (number == UINT_MAX)
194 for (number = 1; get_signature(number) != NULL ; number++);
196 if (!force && get_signature(number) != NULL) {
197 ERROR("can't overwrite existing signature %s", get_signature(number)->name);
201 NOTICE("-- SIGNING content of directory %s for number %u", directory, number);
203 certfiles[ncert] = NULL;
204 return !!create_digsig(number, keyfile, (const char**)certfiles);