xref: /netbsd-src/crypto/dist/ipsec-tools/src/racoon/prsa_par.y (revision 582ad8c19fc1f6ead58c5b2d1ba4067d566e8d6e)
1 /*	$NetBSD: prsa_par.y,v 1.8 2022/01/23 14:55:28 christos Exp $	*/
2 
3 /* Id: prsa_par.y,v 1.3 2004/11/08 12:04:23 ludvigm Exp */
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 
61 #include <openssl/bn.h>
62 #include <openssl/rsa.h>
63 
64 #include "misc.h"
65 #include "vmbuf.h"
66 #include "plog.h"
67 #include "oakley.h"
68 #include "isakmp_var.h"
69 #include "handler.h"
70 #include "crypto_openssl.h"
71 #include "sockmisc.h"
72 #include "rsalist.h"
73 
74 extern void prsaerror(const char *str, ...);
75 extern int prsawrap (void);
76 extern int prsalex (void);
77 
78 extern char *prsatext;
79 extern int prsa_cur_lineno;
80 extern char *prsa_cur_fname;
81 extern FILE *prsain;
82 
83 int prsa_cur_lineno = 0;
84 char *prsa_cur_fname = NULL;
85 struct genlist *prsa_cur_list = NULL;
86 enum rsa_key_type prsa_cur_type = RSA_TYPE_ANY;
87 
88 static RSA *rsa_cur;
89 
90 static BIGNUM *bn_n = NULL; /* Modulus */
91 static BIGNUM *bn_e = NULL; /* Public Exponent */
92 static BIGNUM *bn_d = NULL; /* Private Exponent */
93 static BIGNUM *bn_p = NULL; /* Prime1 */
94 static BIGNUM *bn_q = NULL; /* Prime2 */
95 static BIGNUM *bn_dmp1 = NULL; /* Exponent1 */
96 static BIGNUM *bn_dmq1 = NULL; /* Exponent2 */
97 static BIGNUM *bn_iqmp = NULL; /* Coefficient */
98 
99 void
prsaerror(const char * s,...)100 prsaerror(const char *s, ...)
101 {
102 	char fmt[512];
103 
104 	va_list ap;
105 #ifdef HAVE_STDARG_H
106 	va_start(ap, s);
107 #else
108 	va_start(ap);
109 #endif
110 	snprintf(fmt, sizeof(fmt), "%s:%d: %s",
111 		prsa_cur_fname, prsa_cur_lineno, s);
112 	plogv(LLV_ERROR, LOCATION, NULL, fmt, ap);
113 	va_end(ap);
114 }
115 
116 void
prsawarning(const char * s,...)117 prsawarning(const char *s, ...)
118 {
119 	char fmt[512];
120 
121 	va_list ap;
122 #ifdef HAVE_STDARG_H
123 	va_start(ap, s);
124 #else
125 	va_start(ap);
126 #endif
127 	snprintf(fmt, sizeof(fmt), "%s:%d: %s",
128 		prsa_cur_fname, prsa_cur_lineno, s);
129 	plogv(LLV_WARNING, LOCATION, NULL, fmt, ap);
130 	va_end(ap);
131 }
132 
133 int
prsawrap()134 prsawrap()
135 {
136 	return 1;
137 }
138 %}
139 %union {
140 	BIGNUM *bn;
141 	RSA *rsa;
142 	char *chr;
143 	long num;
144 	struct netaddr *naddr;
145 }
146 
147 %token COLON HEX
148 %token OBRACE EBRACE COLON HEX
149 %token TAG_RSA TAG_PUB TAG_PSK
150 %token MODULUS PUBLIC_EXPONENT PRIVATE_EXPONENT
151 %token PRIME1 PRIME2 EXPONENT1 EXPONENT2 COEFFICIENT
152 %token ADDR4 ADDR6 ADDRANY SLASH NUMBER BASE64
153 
154 %type <bn>	HEX
155 %type <num>	NUMBER
156 %type <chr>	ADDR4 ADDR6 BASE64
157 
158 %type <rsa>	rsa_statement
159 %type <num>	prefix
160 %type <naddr>	addr4 addr6 addr
161 
162 %%
163 statements:
164 	statements statement
165 	| statement
166 	;
167 
168 statement:
169 	addr addr COLON rsa_statement
170 	{
171 		rsa_key_insert(prsa_cur_list, $1, $2, $4);
172 	}
173 	| addr COLON rsa_statement
174 	{
175 		rsa_key_insert(prsa_cur_list, NULL, $1, $3);
176 	}
177 	| COLON rsa_statement
178 	{
179 		rsa_key_insert(prsa_cur_list, NULL, NULL, $2);
180 	}
181 	;
182 
183 rsa_statement:
184 	TAG_RSA OBRACE params EBRACE
185 	{
186 		if (prsa_cur_type == RSA_TYPE_PUBLIC) {
187 			prsawarning("Using private key for public key purpose.\n");
188 			if (!bn_n || !bn_e) {
189 				prsaerror("Either of mandatory public key parameters "
190 						" - n, d - are missing!\n");
191 				YYABORT;
192 			} else if (1 != RSA_set0_key(rsa_cur, bn_n, bn_e, NULL)) {
193 				prsaerror("Invalid parameters. Public key not set up!\n");
194 				YYABORT;
195 			}
196 		} else {
197 			if (!bn_n || !bn_e || !bn_d) {
198 				prsaerror("Either of mandatory private key parameters "
199 						"- n, e, d -- are missing!\n");
200 				YYABORT;
201 			} else if (1 != RSA_set0_key(rsa_cur, bn_n, bn_e, bn_d)) {
202 				prsaerror("Can not use mandatory private key parameters!\n");
203 				YYABORT;
204 			} else if (!bn_p || !bn_q || !bn_dmp1 || !bn_dmq1 || !bn_iqmp) {
205 				/* If any of the suplementary parameters is missing, continue
206 				 * without setting them up.
207 				 */
208 			} else if (1 != RSA_set0_factors(rsa_cur, bn_p, bn_q)) {
209 				prsaerror("Invalid p or q parameter. Private key not set up!\n");
210 				YYABORT;
211 			} else if (1 != RSA_set0_crt_params(rsa_cur, bn_dmp1, bn_dmq1, bn_iqmp)) {
212 				prsaerror("Invalid dmp1, dmq1 or iqmp parameters. "
213 						"Private key not set up!\n");
214 				YYABORT;
215 			}
216 		}
217 		$$ = rsa_cur;
218 		rsa_cur = RSA_new();
219 	}
220 	| TAG_PUB BASE64
221 	{
222 		if (prsa_cur_type == RSA_TYPE_PRIVATE) {
223 			prsaerror("Public key in private-key file!\n");
224 			YYABORT;
225 		}
226 		$$ = base64_pubkey2rsa($2);
227 		free($2);
228 	}
229 	| TAG_PUB HEX
230 	{
231 		if (prsa_cur_type == RSA_TYPE_PRIVATE) {
232 			prsaerror("Public key in private-key file!\n");
233 			YYABORT;
234 		}
235 		$$ = bignum_pubkey2rsa($2);
236 	}
237 	;
238 
239 addr:
240 	addr4
241 	| addr6
242 	| ADDRANY
243 	{
244 		$$ = NULL;
245 	}
246 	;
247 
248 addr4:
249 	ADDR4 prefix
250 	{
251 		int err;
252 		struct sockaddr_in *sap;
253 		struct addrinfo hints, *res;
254 
255 		if ($2 == -1) $2 = 32;
256 		if ($2 < 0 || $2 > 32) {
257 			prsaerror ("Invalid IPv4 prefix\n");
258 			YYABORT;
259 		}
260 		$$ = calloc (sizeof(struct netaddr), 1);
261 		$$->prefix = $2;
262 		sap = (struct sockaddr_in *)(&$$->sa);
263 		memset(&hints, 0, sizeof(hints));
264 		hints.ai_family = AF_INET;
265 		hints.ai_flags = AI_NUMERICHOST;
266 		err = getaddrinfo($1, NULL, &hints, &res);
267 		if (err < 0) {
268 			prsaerror("getaddrinfo(%s): %s\n", $1, gai_strerror(err));
269 			YYABORT;
270 		}
271 		memcpy(sap, res->ai_addr, res->ai_addrlen);
272 		freeaddrinfo(res);
273 		free($1);
274 	}
275 	;
276 
277 addr6:
278 	ADDR6 prefix
279 	{
280 		int err;
281 		struct sockaddr_in6 *sap;
282 		struct addrinfo hints, *res;
283 
284 		if ($2 == -1) $2 = 128;
285 		if ($2 < 0 || $2 > 128) {
286 			prsaerror ("Invalid IPv6 prefix\n");
287 			YYABORT;
288 		}
289 		$$ = calloc (sizeof(struct netaddr), 1);
290 		$$->prefix = $2;
291 		sap = (struct sockaddr_in6 *)(&$$->sa);
292 		memset(&hints, 0, sizeof(hints));
293 		hints.ai_family = AF_INET6;
294 		hints.ai_flags = AI_NUMERICHOST;
295 		err = getaddrinfo($1, NULL, &hints, &res);
296 		if (err < 0) {
297 			prsaerror("getaddrinfo(%s): %s\n", $1, gai_strerror(err));
298 			YYABORT;
299 		}
300 		memcpy(sap, res->ai_addr, res->ai_addrlen);
301 		freeaddrinfo(res);
302 		free($1);
303 	}
304 	;
305 
306 prefix:
307 	/* nothing */ { $$ = -1; }
308 	| SLASH NUMBER { $$ = $2; }
309 	;
310 params:
311 	params param
312 	| param
313 	;
314 
315 param:
316 	MODULUS COLON HEX
317 	{
318 		if (bn_n) {
319 			prsaerror("Modulus already defined\n");
320 			YYABORT;
321 		} else {
322 			bn_n = $3;
323 		}
324 	}
325 	| PUBLIC_EXPONENT COLON HEX
326 	{
327 		if (bn_e) {
328 			prsaerror("PublicExponent already defined\n");
329 			YYABORT;
330 		} else {
331 			bn_e = $3;
332 		}
333 	}
334 	| PRIVATE_EXPONENT COLON HEX
335 	{
336 		if (bn_d) {
337 			prsaerror("PrivateExponent already defined\n");
338 			YYABORT;
339 		} else {
340 			bn_d = $3;
341 		}
342 	}
343 	| PRIME1 COLON HEX
344 	{
345 		if (bn_p) {
346 			prsaerror("Prime1 already defined\n");
347 			YYABORT;
348 		} else {
349 			bn_p = $3;
350 		}
351 	}
352 	| PRIME2 COLON HEX
353 	{
354 		if (bn_q) {
355 			prsaerror("Prime2 already defined\n");
356 			YYABORT;
357 		} else {
358 			bn_q = $3;
359 		}
360 	}
361 	| EXPONENT1 COLON HEX
362 	{
363 		if (bn_dmp1) {
364 			prsaerror("Exponent1 already defined\n");
365 			YYABORT;
366 		} else {
367 			bn_dmp1 = $3;
368 		}
369 	}
370 	| EXPONENT2 COLON HEX
371 	{
372 		if (bn_dmq1) {
373 			prsaerror("Exponent2 already defined\n");
374 			YYABORT;
375 		} else {
376 			bn_dmq1 = $3;
377 		}
378 	}
379 	| COEFFICIENT COLON HEX
380 	{
381 		if (bn_iqmp) {
382 			prsaerror("Coefficient already defined\n");
383 			YYABORT;
384 		} else {
385 			bn_iqmp = $3;
386 		}
387 	}
388 	;
389 %%
390 
391 int prsaparse(void);
392 
393 int
prsa_parse_file(struct genlist * list,char * fname,enum rsa_key_type type)394 prsa_parse_file(struct genlist *list, char *fname, enum rsa_key_type type)
395 {
396 	FILE *fp = NULL;
397 	int ret;
398 
399 	if (!fname)
400 		return -1;
401 	if (type == RSA_TYPE_PRIVATE) {
402 		struct stat st;
403 		if (stat(fname, &st) < 0)
404 			return -1;
405 		if (st.st_mode & (S_IRWXG | S_IRWXO)) {
406 			plog(LLV_ERROR, LOCATION, NULL,
407 				"Too slack permissions on private key '%s'\n",
408 				fname);
409 			plog(LLV_ERROR, LOCATION, NULL,
410 				"Should be at most 0600, now is 0%o\n",
411 				st.st_mode & 0777);
412 			return -1;
413 		}
414 	}
415 	fp = fopen(fname, "r");
416 	if (!fp)
417 		return -1;
418 	prsain = fp;
419 	prsa_cur_lineno = 1;
420 	prsa_cur_fname = fname;
421 	prsa_cur_list = list;
422 	prsa_cur_type = type;
423 	rsa_cur = RSA_new();
424 	ret = prsaparse();
425 	if (rsa_cur) {
426 		RSA_free(rsa_cur);
427 		rsa_cur = NULL;
428 	}
429 	fclose (fp);
430 	prsain = NULL;
431 	return ret;
432 }
433