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