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