File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / prsa_par.y
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:39:10 2012 UTC (12 years, 4 months ago) by misho
Branches: ipsec-tools, MAIN
CVS tags: v0_8_2p2, v0_8_1p0, v0_8_1, v0_8_0p0, v0_8_0, HEAD
ipsec-tools

    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>