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

6-freebsd-12
Last change on this file was b376ae1, checked in by Christian Mauderer <christian.mauderer@…>, on 05/03/18 at 12:15:11

ipsec-tools: Port libipsec, setkey and racoon.

Note that this replaces the libipsec from FreeBSD with the one provided
by ipsec-tools.

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