]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/prsa_par.y
ipsec-34.0.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / prsa_par.y
1 /* $Id: prsa_par.y,v 1.3 2004/11/08 12:04:23 ludvigm Exp $ */
2
3 %{
4 /*
5 * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
6 * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 /* This file contains a parser for FreeS/WAN-style ipsec.secrets RSA keys. */
35
36 #include "config.h"
37
38 #include <stdio.h>
39 #include <stdarg.h>
40 #include <string.h>
41 #include <errno.h>
42 #include <unistd.h>
43
44 #ifdef HAVE_STDARG_H
45 #include <stdarg.h>
46 #else
47 #include <varargs.h>
48 #endif
49
50 #include <netdb.h>
51 #include <netinet/in.h>
52 #include <sys/socket.h>
53 #include <arpa/inet.h>
54 #include <sys/types.h>
55
56 #include <sys/stat.h>
57 #include <unistd.h>
58
59 #include <openssl/bn.h>
60 #include <openssl/rsa.h>
61
62 #include "misc.h"
63 #include "vmbuf.h"
64 #include "plog.h"
65 #include "oakley.h"
66 #include "isakmp_var.h"
67 #include "handler.h"
68 #include "crypto_openssl.h"
69 #include "sockmisc.h"
70 #include "rsalist.h"
71
72 extern void prsaerror(const char *str, ...);
73 extern int prsawrap (void);
74 extern int prsalex (void);
75
76 extern char *prsatext;
77 extern int prsa_cur_lineno;
78 extern char *prsa_cur_fname;
79 extern FILE *prsain;
80
81 int prsa_cur_lineno = 0;
82 char *prsa_cur_fname = NULL;
83 struct genlist *prsa_cur_list = NULL;
84 enum rsa_key_type prsa_cur_type = RSA_TYPE_ANY;
85
86 static RSA *rsa_cur;
87
88 void
89 prsaerror(const char *s, ...)
90 {
91 char fmt[512];
92
93 va_list ap;
94 #ifdef HAVE_STDARG_H
95 va_start(ap, s);
96 #else
97 va_start(ap);
98 #endif
99 snprintf(fmt, sizeof(fmt), "%s:%d: %s",
100 prsa_cur_fname, prsa_cur_lineno, s);
101 plogv(LLV_ERROR, LOCATION, NULL, fmt, ap);
102 va_end(ap);
103 }
104
105 void
106 prsawarning(const char *s, ...)
107 {
108 char fmt[512];
109
110 va_list ap;
111 #ifdef HAVE_STDARG_H
112 va_start(ap, s);
113 #else
114 va_start(ap);
115 #endif
116 snprintf(fmt, sizeof(fmt), "%s:%d: %s",
117 prsa_cur_fname, prsa_cur_lineno, s);
118 plogv(LLV_WARNING, LOCATION, NULL, fmt, ap);
119 va_end(ap);
120 }
121
122 int
123 prsawrap()
124 {
125 return 1;
126 }
127 %}
128 %union {
129 BIGNUM *bn;
130 RSA *rsa;
131 char *chr;
132 long num;
133 struct netaddr *naddr;
134 }
135
136 %token COLON HEX
137 %token OBRACE EBRACE COLON HEX
138 %token TAG_RSA TAG_PUB TAG_PSK
139 %token MODULUS PUBLIC_EXPONENT PRIVATE_EXPONENT
140 %token PRIME1 PRIME2 EXPONENT1 EXPONENT2 COEFFICIENT
141 %token ADDR4 ADDR6 ADDRANY SLASH NUMBER BASE64
142
143 %type <bn> HEX
144 %type <num> NUMBER
145 %type <chr> ADDR4 ADDR6 BASE64
146
147 %type <rsa> rsa_statement
148 %type <num> prefix
149 %type <naddr> addr4 addr6 addr
150
151 %%
152 statements:
153 statements statement
154 | statement
155 ;
156
157 statement:
158 addr addr COLON rsa_statement
159 {
160 rsa_key_insert(prsa_cur_list, $1, $2, $4);
161 }
162 | addr COLON rsa_statement
163 {
164 rsa_key_insert(prsa_cur_list, NULL, $1, $3);
165 }
166 | COLON rsa_statement
167 {
168 rsa_key_insert(prsa_cur_list, NULL, NULL, $2);
169 }
170 ;
171
172 rsa_statement:
173 TAG_RSA OBRACE params EBRACE
174 {
175 if (prsa_cur_type == RSA_TYPE_PUBLIC) {
176 prsawarning("Using private key for public key purpose.\n");
177 if (!rsa_cur->n || !rsa_cur->e) {
178 prsaerror("Incomplete key. Mandatory parameters are missing!\n");
179 YYABORT;
180 }
181 }
182 else {
183 if (!rsa_cur->n || !rsa_cur->e || !rsa_cur->d) {
184 prsaerror("Incomplete key. Mandatory parameters are missing!\n");
185 YYABORT;
186 }
187 if (!rsa_cur->p || !rsa_cur->q || !rsa_cur->dmp1
188 || !rsa_cur->dmq1 || !rsa_cur->iqmp) {
189 if (rsa_cur->p) BN_clear_free(rsa_cur->p);
190 if (rsa_cur->q) BN_clear_free(rsa_cur->q);
191 if (rsa_cur->dmp1) BN_clear_free(rsa_cur->dmp1);
192 if (rsa_cur->dmq1) BN_clear_free(rsa_cur->dmq1);
193 if (rsa_cur->iqmp) BN_clear_free(rsa_cur->iqmp);
194
195 rsa_cur->p = NULL;
196 rsa_cur->q = NULL;
197 rsa_cur->dmp1 = NULL;
198 rsa_cur->dmq1 = NULL;
199 rsa_cur->iqmp = NULL;
200 }
201 }
202 $$ = rsa_cur;
203 rsa_cur = RSA_new();
204 }
205 | TAG_PUB BASE64
206 {
207 if (prsa_cur_type == RSA_TYPE_PRIVATE) {
208 prsaerror("Public key in private-key file!\n");
209 YYABORT;
210 }
211 $$ = base64_pubkey2rsa($2);
212 }
213 | TAG_PUB HEX
214 {
215 if (prsa_cur_type == RSA_TYPE_PRIVATE) {
216 prsaerror("Public key in private-key file!\n");
217 YYABORT;
218 }
219 $$ = bignum_pubkey2rsa($2);
220 }
221 ;
222
223 addr:
224 addr4
225 | addr6
226 | ADDRANY
227 {
228 $$ = NULL;
229 }
230 ;
231
232 addr4:
233 ADDR4 prefix
234 {
235 int err;
236 struct sockaddr_in *sap;
237
238 if ($2 == -1) $2 = 32;
239 if ($2 < 0 || $2 > 32) {
240 prsaerror ("Invalid IPv4 prefix\n");
241 YYABORT;
242 }
243 $$ = calloc (sizeof(struct netaddr), 1);
244 $$->prefix = $2;
245 sap = (struct sockaddr_in *)(&$$->sa);
246 sap->sin_family = AF_INET;
247 err = inet_pton(AF_INET, $1, (struct in_addr*)(&sap->sin_addr));
248 if (err <= 0) {
249 prsaerror("inet_pton(%s): %s\n", $1, strerror(errno));
250 YYABORT;
251 }
252 }
253 ;
254
255 addr6:
256 ADDR6 prefix
257 {
258 int err;
259 struct sockaddr_in6 *sap;
260
261 if ($2 == -1) $2 = 128;
262 if ($2 < 0 || $2 > 128) {
263 prsaerror ("Invalid IPv6 prefix\n");
264 YYABORT;
265 }
266 $$ = calloc (sizeof(struct netaddr), 1);
267 $$->prefix = $2;
268 sap = (struct sockaddr_in6 *)(&$$->sa);
269 sap->sin6_family = AF_INET6;
270 err = inet_pton(AF_INET6, $1, (struct in6_addr*)(&sap->sin6_addr));
271 if (err <= 0) {
272 prsaerror("inet_pton(%s): %s\n", $1, strerror(errno));
273 YYABORT;
274 }
275 }
276 ;
277
278 prefix:
279 /* nothing */ { $$ = -1; }
280 | SLASH NUMBER { $$ = $2; }
281 ;
282 params:
283 params param
284 | param
285 ;
286
287 param:
288 MODULUS COLON HEX
289 { if (!rsa_cur->n) rsa_cur->n = $3; else { prsaerror ("Modulus already defined\n"); YYABORT; } }
290 | PUBLIC_EXPONENT COLON HEX
291 { if (!rsa_cur->e) rsa_cur->e = $3; else { prsaerror ("PublicExponent already defined\n"); YYABORT; } }
292 | PRIVATE_EXPONENT COLON HEX
293 { if (!rsa_cur->d) rsa_cur->d = $3; else { prsaerror ("PrivateExponent already defined\n"); YYABORT; } }
294 | PRIME1 COLON HEX
295 { if (!rsa_cur->p) rsa_cur->p = $3; else { prsaerror ("Prime1 already defined\n"); YYABORT; } }
296 | PRIME2 COLON HEX
297 { if (!rsa_cur->q) rsa_cur->q = $3; else { prsaerror ("Prime2 already defined\n"); YYABORT; } }
298 | EXPONENT1 COLON HEX
299 { if (!rsa_cur->dmp1) rsa_cur->dmp1 = $3; else { prsaerror ("Exponent1 already defined\n"); YYABORT; } }
300 | EXPONENT2 COLON HEX
301 { if (!rsa_cur->dmq1) rsa_cur->dmq1 = $3; else { prsaerror ("Exponent2 already defined\n"); YYABORT; } }
302 | COEFFICIENT COLON HEX
303 { if (!rsa_cur->iqmp) rsa_cur->iqmp = $3; else { prsaerror ("Coefficient already defined\n"); YYABORT; } }
304 ;
305 %%
306
307 int prsaparse(void);
308
309 int
310 prsa_parse_file(struct genlist *list, char *fname, enum rsa_key_type type)
311 {
312 FILE *fp = NULL;
313 int ret;
314
315 if (!fname)
316 return -1;
317 if (type == RSA_TYPE_PRIVATE) {
318 struct stat st;
319 if (stat(fname, &st) < 0)
320 return -1;
321 if (st.st_mode & (S_IRWXG | S_IRWXO)) {
322 plog(LLV_ERROR, LOCATION, NULL,
323 "Too slack permissions on private key '%s'\n",
324 fname);
325 plog(LLV_ERROR, LOCATION, NULL,
326 "Should be at most 0600, now is 0%o\n",
327 st.st_mode & 0777);
328 return -1;
329 }
330 }
331 fp = fopen(fname, "r");
332 if (!fp)
333 return -1;
334 prsain = fp;
335 prsa_cur_lineno = 1;
336 prsa_cur_fname = fname;
337 prsa_cur_list = list;
338 prsa_cur_type = type;
339 rsa_cur = RSA_new();
340 ret = prsaparse();
341 if (rsa_cur) {
342 RSA_free(rsa_cur);
343 rsa_cur = NULL;
344 }
345 fclose (fp);
346 prsain = NULL;
347 return ret;
348 }