Annotation of embedaddon/ipsec-tools/src/racoon/prsa_par.y, revision 1.1.1.1
1.1 misho 1: /* $NetBSD: prsa_par.y,v 1.6 2011/03/02 14:49:21 vanhu 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: void
91: prsaerror(const char *s, ...)
92: {
93: char fmt[512];
94:
95: va_list ap;
96: #ifdef HAVE_STDARG_H
97: va_start(ap, s);
98: #else
99: va_start(ap);
100: #endif
101: snprintf(fmt, sizeof(fmt), "%s:%d: %s",
102: prsa_cur_fname, prsa_cur_lineno, s);
103: plogv(LLV_ERROR, LOCATION, NULL, fmt, ap);
104: va_end(ap);
105: }
106:
107: void
108: prsawarning(const char *s, ...)
109: {
110: char fmt[512];
111:
112: va_list ap;
113: #ifdef HAVE_STDARG_H
114: va_start(ap, s);
115: #else
116: va_start(ap);
117: #endif
118: snprintf(fmt, sizeof(fmt), "%s:%d: %s",
119: prsa_cur_fname, prsa_cur_lineno, s);
120: plogv(LLV_WARNING, LOCATION, NULL, fmt, ap);
121: va_end(ap);
122: }
123:
124: int
125: prsawrap()
126: {
127: return 1;
128: }
129: %}
130: %union {
131: BIGNUM *bn;
132: RSA *rsa;
133: char *chr;
134: long num;
135: struct netaddr *naddr;
136: }
137:
138: %token COLON HEX
139: %token OBRACE EBRACE COLON HEX
140: %token TAG_RSA TAG_PUB TAG_PSK
141: %token MODULUS PUBLIC_EXPONENT PRIVATE_EXPONENT
142: %token PRIME1 PRIME2 EXPONENT1 EXPONENT2 COEFFICIENT
143: %token ADDR4 ADDR6 ADDRANY SLASH NUMBER BASE64
144:
145: %type <bn> HEX
146: %type <num> NUMBER
147: %type <chr> ADDR4 ADDR6 BASE64
148:
149: %type <rsa> rsa_statement
150: %type <num> prefix
151: %type <naddr> addr4 addr6 addr
152:
153: %%
154: statements:
155: statements statement
156: | statement
157: ;
158:
159: statement:
160: addr addr COLON rsa_statement
161: {
162: rsa_key_insert(prsa_cur_list, $1, $2, $4);
163: }
164: | addr COLON rsa_statement
165: {
166: rsa_key_insert(prsa_cur_list, NULL, $1, $3);
167: }
168: | COLON rsa_statement
169: {
170: rsa_key_insert(prsa_cur_list, NULL, NULL, $2);
171: }
172: ;
173:
174: rsa_statement:
175: TAG_RSA OBRACE params EBRACE
176: {
177: if (prsa_cur_type == RSA_TYPE_PUBLIC) {
178: prsawarning("Using private key for public key purpose.\n");
179: if (!rsa_cur->n || !rsa_cur->e) {
180: prsaerror("Incomplete key. Mandatory parameters are missing!\n");
181: YYABORT;
182: }
183: }
184: else {
185: if (!rsa_cur->n || !rsa_cur->e || !rsa_cur->d) {
186: prsaerror("Incomplete key. Mandatory parameters are missing!\n");
187: YYABORT;
188: }
189: if (!rsa_cur->p || !rsa_cur->q || !rsa_cur->dmp1
190: || !rsa_cur->dmq1 || !rsa_cur->iqmp) {
191: if (rsa_cur->p) BN_clear_free(rsa_cur->p);
192: if (rsa_cur->q) BN_clear_free(rsa_cur->q);
193: if (rsa_cur->dmp1) BN_clear_free(rsa_cur->dmp1);
194: if (rsa_cur->dmq1) BN_clear_free(rsa_cur->dmq1);
195: if (rsa_cur->iqmp) BN_clear_free(rsa_cur->iqmp);
196:
197: rsa_cur->p = NULL;
198: rsa_cur->q = NULL;
199: rsa_cur->dmp1 = NULL;
200: rsa_cur->dmq1 = NULL;
201: rsa_cur->iqmp = NULL;
202: }
203: }
204: $$ = rsa_cur;
205: rsa_cur = RSA_new();
206: }
207: | TAG_PUB BASE64
208: {
209: if (prsa_cur_type == RSA_TYPE_PRIVATE) {
210: prsaerror("Public key in private-key file!\n");
211: YYABORT;
212: }
213: $$ = base64_pubkey2rsa($2);
214: free($2);
215: }
216: | TAG_PUB HEX
217: {
218: if (prsa_cur_type == RSA_TYPE_PRIVATE) {
219: prsaerror("Public key in private-key file!\n");
220: YYABORT;
221: }
222: $$ = bignum_pubkey2rsa($2);
223: }
224: ;
225:
226: addr:
227: addr4
228: | addr6
229: | ADDRANY
230: {
231: $$ = NULL;
232: }
233: ;
234:
235: addr4:
236: ADDR4 prefix
237: {
238: int err;
239: struct sockaddr_in *sap;
240: struct addrinfo hints, *res;
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: memset(&hints, 0, sizeof(hints));
251: hints.ai_family = AF_INET;
252: hints.ai_flags = AI_NUMERICHOST;
253: err = getaddrinfo($1, NULL, &hints, &res);
254: if (err < 0) {
255: prsaerror("getaddrinfo(%s): %s\n", $1, gai_strerror(err));
256: YYABORT;
257: }
258: memcpy(sap, res->ai_addr, res->ai_addrlen);
259: freeaddrinfo(res);
260: free($1);
261: }
262: ;
263:
264: addr6:
265: ADDR6 prefix
266: {
267: int err;
268: struct sockaddr_in6 *sap;
269: struct addrinfo hints, *res;
270:
271: if ($2 == -1) $2 = 128;
272: if ($2 < 0 || $2 > 128) {
273: prsaerror ("Invalid IPv6 prefix\n");
274: YYABORT;
275: }
276: $$ = calloc (sizeof(struct netaddr), 1);
277: $$->prefix = $2;
278: sap = (struct sockaddr_in6 *)(&$$->sa);
279: memset(&hints, 0, sizeof(hints));
280: hints.ai_family = AF_INET6;
281: hints.ai_flags = AI_NUMERICHOST;
282: err = getaddrinfo($1, NULL, &hints, &res);
283: if (err < 0) {
284: prsaerror("getaddrinfo(%s): %s\n", $1, gai_strerror(err));
285: YYABORT;
286: }
287: memcpy(sap, res->ai_addr, res->ai_addrlen);
288: freeaddrinfo(res);
289: free($1);
290: }
291: ;
292:
293: prefix:
294: /* nothing */ { $$ = -1; }
295: | SLASH NUMBER { $$ = $2; }
296: ;
297: params:
298: params param
299: | param
300: ;
301:
302: param:
303: MODULUS COLON HEX
304: { if (!rsa_cur->n) rsa_cur->n = $3; else { prsaerror ("Modulus already defined\n"); YYABORT; } }
305: | PUBLIC_EXPONENT COLON HEX
306: { if (!rsa_cur->e) rsa_cur->e = $3; else { prsaerror ("PublicExponent already defined\n"); YYABORT; } }
307: | PRIVATE_EXPONENT COLON HEX
308: { if (!rsa_cur->d) rsa_cur->d = $3; else { prsaerror ("PrivateExponent already defined\n"); YYABORT; } }
309: | PRIME1 COLON HEX
310: { if (!rsa_cur->p) rsa_cur->p = $3; else { prsaerror ("Prime1 already defined\n"); YYABORT; } }
311: | PRIME2 COLON HEX
312: { if (!rsa_cur->q) rsa_cur->q = $3; else { prsaerror ("Prime2 already defined\n"); YYABORT; } }
313: | EXPONENT1 COLON HEX
314: { if (!rsa_cur->dmp1) rsa_cur->dmp1 = $3; else { prsaerror ("Exponent1 already defined\n"); YYABORT; } }
315: | EXPONENT2 COLON HEX
316: { if (!rsa_cur->dmq1) rsa_cur->dmq1 = $3; else { prsaerror ("Exponent2 already defined\n"); YYABORT; } }
317: | COEFFICIENT COLON HEX
318: { if (!rsa_cur->iqmp) rsa_cur->iqmp = $3; else { prsaerror ("Coefficient already defined\n"); YYABORT; } }
319: ;
320: %%
321:
322: int prsaparse(void);
323:
324: int
325: prsa_parse_file(struct genlist *list, char *fname, enum rsa_key_type type)
326: {
327: FILE *fp = NULL;
328: int ret;
329:
330: if (!fname)
331: return -1;
332: if (type == RSA_TYPE_PRIVATE) {
333: struct stat st;
334: if (stat(fname, &st) < 0)
335: return -1;
336: if (st.st_mode & (S_IRWXG | S_IRWXO)) {
337: plog(LLV_ERROR, LOCATION, NULL,
338: "Too slack permissions on private key '%s'\n",
339: fname);
340: plog(LLV_ERROR, LOCATION, NULL,
341: "Should be at most 0600, now is 0%o\n",
342: st.st_mode & 0777);
343: return -1;
344: }
345: }
346: fp = fopen(fname, "r");
347: if (!fp)
348: return -1;
349: prsain = fp;
350: prsa_cur_lineno = 1;
351: prsa_cur_fname = fname;
352: prsa_cur_list = list;
353: prsa_cur_type = type;
354: rsa_cur = RSA_new();
355: ret = prsaparse();
356: if (rsa_cur) {
357: RSA_free(rsa_cur);
358: rsa_cur = NULL;
359: }
360: fclose (fp);
361: prsain = NULL;
362: return ret;
363: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>