source: rtems-libbsd/ipsec-tools/src/racoon/prsa_par.y @ ff36f5e

5-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on May 30, 2018 at 12:27:35 PM

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

  • Property mode set to 100644
File size: 8.5 KB
Line 
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
74extern void prsaerror(const char *str, ...);
75extern int prsawrap (void);
76extern int prsalex (void);
77
78extern char *prsatext;
79extern int prsa_cur_lineno;
80extern char *prsa_cur_fname;
81extern FILE *prsain;
82
83int prsa_cur_lineno = 0;
84char *prsa_cur_fname = NULL;
85struct genlist *prsa_cur_list = NULL;
86enum rsa_key_type prsa_cur_type = RSA_TYPE_ANY;
87
88static RSA *rsa_cur;
89
90void
91prsaerror(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
107void
108prsawarning(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
124int
125prsawrap()
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%%
154statements:
155        statements statement
156        | statement
157        ;
158
159statement:
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
174rsa_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
226addr:
227        addr4
228        | addr6
229        | ADDRANY
230        {
231                $$ = NULL;
232        }
233        ;
234
235addr4:
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
264addr6:
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
293prefix:
294        /* nothing */ { $$ = -1; }
295        | SLASH NUMBER { $$ = $2; }
296        ;
297params:
298        params param
299        | param
300        ;
301
302param:
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
322int prsaparse(void);
323
324int
325prsa_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}
Note: See TracBrowser for help on using the repository browser.