Annotation of embedaddon/ipsec-tools/src/racoon/prsa_par.y, revision 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>