1 /*
2  * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
3  *
4  * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
5  * in April-May 1998
6  *
7  * Copyright (C) 1998, 1999 by Angelos D. Keromytis.
8  *
9  * Permission to use, copy, and modify this software without fee
10  * is hereby granted, provided that this entire notice is included in
11  * all copies of any software which is or includes a copy or
12  * modification of this software.
13  *
14  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
16  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
17  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
18  * PURPOSE.
19  */
20 
21 #if HAVE_CONFIG_H
22 #include "config.h"
23 #endif /* HAVE_CONFIG_H */
24 
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <ctype.h>
30 
31 #if STDC_HEADERS
32 #include <string.h>
33 #endif /* STDC_HEADERS */
34 
35 #if HAVE_FCNTL_H
36 #include <fcntl.h>
37 #endif /* HAVE_FCNTL_H */
38 
39 #if HAVE_IO_H
40 #include <io.h>
41 #elif HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif /* HAVE_IO_H */
44 
45 #include "header.h"
46 #include "keynote.h"
47 
48 void
signusage(void)49 signusage(void)
50 {
51     fprintf(stderr, "Arguments:\n");
52     fprintf(stderr, "\t[-v] <AlgorithmName> <AssertionFile> "
53 	    "<PrivateKeyFile> [<print-offset>] [<print-length>]\n");
54 }
55 
56 void
keynote_sign(int argc,char * argv[])57 keynote_sign(int argc, char *argv[])
58 {
59     int begin = SIG_PRINT_OFFSET, prlen = SIG_PRINT_LENGTH;
60     char *buf, *buf2, *sig, *algname;
61     int fd, flg = 0, buflen;
62     struct stat sb;
63 
64     if ((argc != 4) &&
65 	(argc != 5) &&
66 	(argc != 6) &&
67 	(argc != 7))
68     {
69 	signusage();
70 	exit(-1);
71     }
72 
73     if (!strcmp("-v", argv[1]))
74       flg = 1;
75 
76     if (argc > 4 + flg)
77     {
78         begin = atoi(argv[4 + flg]);
79         if (begin <= -1)
80         {
81             fprintf(stderr, "Erroneous value for print-offset parameter.\n");
82             exit(-1);
83         }
84     }
85 
86     if (argc > 5 + flg)
87     {
88         prlen = atoi(argv[5 + flg]);
89         if (prlen <= 0)
90         {
91             fprintf(stderr, "Erroneous value for print-length parameter.\n");
92             exit(-1);
93         }
94     }
95 
96     /* Fix algorithm name */
97     if (argv[1 + flg][strlen(argv[1 + flg]) - 1] != ':')
98     {
99         fprintf(stderr, "Algorithm name [%s] should be terminated with a "
100 		"colon, fixing.\n", argv[1 + flg]);
101 	algname = (char *) calloc(strlen(argv[1 + flg]) + 2, sizeof(char));
102 	if (algname == (char *) NULL)
103 	{
104 	    perror("calloc()");
105 	    exit(-1);
106 	}
107 
108 	strcpy(algname, argv[1 + flg]);
109 	algname[strlen(algname)] = ':';
110     }
111     else
112 	algname = argv[1 + flg];
113 
114     /* Read assertion */
115     fd = open(argv[2 + flg], O_RDONLY, 0);
116     if (fd < 0)
117     {
118 	perror(argv[2 + flg]);
119 	exit(-1);
120     }
121 
122     if (fstat(fd, &sb) < 0)
123     {
124 	perror("fstat()");
125 	exit(-1);
126     }
127 
128     if (sb.st_size == 0) /* Paranoid */
129     {
130 	fprintf(stderr, "Error: zero-sized assertion-file.\n");
131 	exit(-1);
132     }
133 
134     buflen = sb.st_size + 1;
135     buf = (char *) calloc(buflen, sizeof(char));
136     if (buf == (char *) NULL)
137     {
138 	perror("calloc()");
139 	exit(-1);
140     }
141 
142     if (read(fd, buf, buflen - 1) < 0)
143     {
144 	perror("read()");
145 	exit(-1);
146     }
147 
148     close(fd);
149 
150     /* Read private key file */
151     fd = open(argv[3 + flg], O_RDONLY, 0);
152     if (fd < 0)
153     {
154 	perror(argv[3 + flg]);
155 	exit(-1);
156     }
157 
158     if (fstat(fd, &sb) < 0)
159     {
160 	perror("fstat()");
161 	exit(-1);
162     }
163 
164     if (sb.st_size == 0) /* Paranoid */
165     {
166 	fprintf(stderr, "Illegal key-file size 0\n");
167 	exit(-1);
168     }
169 
170     buf2 = (char *) calloc(sb.st_size + 1, sizeof(char));
171     if (buf2 == (char *) NULL)
172     {
173 	perror("calloc()");
174 	exit(-1);
175     }
176 
177     if (read(fd, buf2, sb.st_size) < 0)
178     {
179 	perror("read()");
180 	exit(-1);
181     }
182 
183     close(fd);
184 
185     sig = kn_sign_assertion(buf, buflen, buf2, algname, flg);
186 
187     /* Free buffers */
188     free(buf);
189     free(buf2);
190 
191     if (sig == (char *) NULL)
192     {
193 	switch (keynote_errno)
194 	{
195 	    case ERROR_MEMORY:
196 		fprintf(stderr, "Out of memory while creating signature.\n");
197 		break;
198 
199 	    case ERROR_SYNTAX:
200 		fprintf(stderr, "Bad assertion or algorithm format, or "
201 			"unsupported algorithm while creating signature.\n");
202 		break;
203 
204 	    default:
205 		fprintf(stderr, "Unknown error while creating signature.\n");
206 	}
207 
208 	exit(-1);
209     }
210 
211     /* Print signature string */
212     print_key(stdout, "", sig, begin, prlen);
213 
214     free(sig);   /* Just a reminder that the result is malloc'ed */
215 
216     exit(0);
217 }
218