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 syslog(LOG_ERR, "bad number value %s", value);
53 return (unsigned int)val;
59 "usage: %s [-f] [-k keyfile] [-c certfile]... [-o wgtfile] [-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;
93 openlog(appname, LOG_PERROR, LOG_USER);
95 force = ncert = author = 0;
97 keyfile = directory = NULL;
99 i = getopt_long(ac, av, "hfak:c:d:", options, NULL);
104 if (ncert == MAXCERT) {
105 syslog(LOG_ERR, "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;
116 syslog(LOG_ERR, "missing argument");
119 syslog(LOG_ERR, "unrecognized option");
123 syslog(LOG_ERR, "option set twice");
129 /* remaining arguments and final checks */
131 syslog(LOG_ERR, "no directory set");
134 directory = av[optind++];
136 syslog(LOG_ERR, "extra parameters found");
140 /* set default values */
142 keyfile = DEFAULT_KEY_FILE;
144 certfiles[ncert++] = DEFAULT_CERT_FILE;
147 if (stat(directory, &s)) {
148 syslog(LOG_ERR, "can't find directory %s", directory);
151 if (!S_ISDIR(s.st_mode)) {
152 syslog(LOG_ERR, "%s isn't a directory", directory);
155 if (access(keyfile, R_OK) != 0) {
156 syslog(LOG_ERR, "can't access private key %s", keyfile);
159 for(i = 0 ; i < ncert ; i++)
160 if (access(certfiles[i], R_OK) != 0) {
161 syslog(LOG_ERR, "can't access certificate %s", certfiles[i]);
165 /* init xmlsec module */
170 /* compute absolutes paths */
171 #define rp(x) do { char *p = realpath(x, NULL); if (p != NULL) x = p; else { syslog(LOG_ERR, "realpath failed for %s",x); return 1; } } while(0)
173 for(i = 0 ; i < ncert ; i++)
177 /* set and enter the workdir */
178 if (set_workdir(directory, 0) || enter_workdir(0))
186 else if (number == UINT_MAX)
187 for (number = 1; get_signature(number) != NULL ; number++);
189 if (!force && get_signature(number) != NULL) {
190 syslog(LOG_ERR, "can't overwrite existing signature %s", get_signature(number)->name);
194 notice("-- SIGNING content of directory %s for number %u", directory, number);
196 certfiles[ncert] = NULL;
197 return !!create_digsig(number, keyfile, (const char**)certfiles);