2 *------------------------------------------------------------------
3 * sign.c - sign a binary
5 * Jan 2010, George Spelvin
7 * Copyright (c) 2010 Cisco and/or its affiliates.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at:
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *------------------------------------------------------------------
24 #include <sys/types.h>
27 #include <netinet/in.h>
34 #include <vppinfra/clib.h>
35 #include <vppinfra/vec.h>
36 #include <vppinfra/hash.h>
37 #include <vppinfra/bitmap.h>
38 #include <vppinfra/fifo.h>
39 #include <vppinfra/time.h>
40 #include <vppinfra/mheap.h>
41 #include <vppinfra/heap.h>
42 #include <vppinfra/pool.h>
43 #include <vppinfra/format.h>
44 #include <vppinfra/error.h>
45 #include <vppinfra/unix.h>
47 /* Elf-file magic number */
48 static unsigned char elfmag[4] = {0x7F, 'E', 'L', 'F'};
50 int add_signature (char *file, u8 *sigfile)
60 if ((e = unix_file_contents ((char *)sigfile, &sigcontents))) {
61 fformat(stderr, "%v", e->what);
66 siglen = vec_len (sigcontents);
68 vec_add1(sigcontents, (siglen>>24)&0xff);
69 vec_add1(sigcontents, (siglen>>16)&0xff);
70 vec_add1(sigcontents, (siglen>> 8)&0xff);
71 vec_add1(sigcontents, (siglen>> 0)&0xff);
73 /* remember the desired file mode */
74 if (stat(file, &statb) < 0) {
75 fformat(stderr, "Couldn't stat %s\n", file);
78 /* Skip empty / short trout. Don't complain */
79 if (statb.st_size < 4) {
83 /* make it writeable */
86 fd = open (file, O_RDWR | O_APPEND, 0755);
89 fformat (stderr, "Couldn't append to %s\n", file);
94 * We feed this program a list of files with execute permission.
95 * Signing a shell script makes it taste bad, etc. etc.
97 if (read(fd, magic, 4) != 4) {
98 fformat (stderr, "Couldn't read magic number from %s\n", file);
101 for (i = 0; i < 4; i++) {
102 if (magic[i] != elfmag[i]) {
107 if (write (fd, sigcontents, vec_len(sigcontents))
108 != vec_len (sigcontents)) {
109 fformat (stderr, "Write error on %s\n", file);
116 /* restore the file mode */
117 chmod (file, statb.st_mode);
124 int sign_one_file (char *pemfile, char *password, char *file)
129 t1 = format (0, "/tmp/sha256-%d%c", mypid, 0);
130 t2 = format (0, "/tmp/sig-%d%c", mypid, 0);
132 cmd = format (0, "openssl dgst -sha256 < %s > %s%c", file, t1, 0);
133 if (system((char *)cmd)) {
135 clib_warning("'%s' failed", cmd);
140 cmd = format (0, "openssl rsautl -inkey %s -in %s -out %s ",
142 cmd = format (cmd, "-passin pass:%s -sign%c", password, 0);
144 if (system((char *)cmd))
149 if (add_signature (file, t2))
158 /* usage: sign <foo.pem> <password> <list-of-files> */
160 int main (int argc, char **argv)
166 fformat(stderr, "usage: %s <xxx.pem> <password> <list-of-files>\n",
171 for (i = 3; i < argc; i++) {
172 if (sign_one_file (argv[1], argv[2], argv[i])) {
173 fformat(stderr, "Left unsigned: %s\n", argv[i]);