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>