├── VERSION ├── test ├── dec_data.bin ├── sig_data.bin ├── Makefile ├── README.txt ├── cert3.pem ├── cert0.pem ├── cert2.pem ├── cert1.pem └── ca_list.pem ├── vpnc-script-win ├── vpnc.conf ├── vpnc-disconnect ├── crypto-gnutls.h ├── cisco-decrypt.1 ├── decrypt-utils.h ├── crypto-openssl.h ├── vpnc.h ├── pcf2vpnc.1 ├── enum2debug.pl ├── supp.h ├── cisco-decrypt.c ├── dh.h ├── mk-version ├── dh.c ├── math_group.h ├── decrypt-utils.c ├── vpnc-script-win.js ├── nortel.txt ├── tap-win32.h ├── config.h ├── crypto.c ├── tunip.h ├── pcf2vpnc ├── makeman.pl ├── supp.c ├── isakmp-pkt.h ├── test-crypto.c ├── crypto.h ├── TODO ├── Makefile ├── sysdep.h ├── vpnc.8.template ├── README ├── ChangeLog ├── crypto-openssl.c ├── math_group.c ├── isakmp.h └── crypto-gnutls.c /VERSION: -------------------------------------------------------------------------------- 1 | 0.5.3 2 | -------------------------------------------------------------------------------- /test/dec_data.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ndpgroup/vpnc/HEAD/test/dec_data.bin -------------------------------------------------------------------------------- /test/sig_data.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ndpgroup/vpnc/HEAD/test/sig_data.bin -------------------------------------------------------------------------------- /vpnc-script-win: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | cscript `cygpath -w /etc/vpnc/vpnc-script-win.js` 3 | -------------------------------------------------------------------------------- /vpnc.conf: -------------------------------------------------------------------------------- 1 | #IPSec gateway 2 | #IPSec ID 3 | #IPSec secret 4 | #IKE Authmode hybrid 5 | #Xauth username 6 | #Xauth password 7 | -------------------------------------------------------------------------------- /vpnc-disconnect: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | pid=/var/run/vpnc.pid 4 | 5 | if [ $# -ne 0 ]; then 6 | echo "Usage: $0" 1>&2 7 | exit 1 8 | fi 9 | 10 | PID="$(cat "$pid" 2> /dev/null)" 11 | 12 | if [ -z "$PID" ]; then 13 | echo "no vpnc found running" 14 | exit 1 15 | fi 16 | 17 | if ! kill -0 "$PID" > /dev/null 2>&1; then 18 | echo "no vpnc found running" 19 | exit 1 20 | fi 21 | 22 | echo "Terminating vpnc daemon (pid: $PID)" 23 | exec kill $PID 24 | -------------------------------------------------------------------------------- /crypto-gnutls.h: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; either version 2 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #ifndef __CRYPTO_GNUTLS_H__ 19 | #define __CRTPTO_GNUTLS_H__ 20 | 21 | #include 22 | #include 23 | 24 | typedef struct { 25 | int num; 26 | gnutls_x509_crt_t *stack; 27 | } crypto_ctx; 28 | 29 | #endif /* __CRYPTO_GNUTLS_H__ */ 30 | 31 | -------------------------------------------------------------------------------- /cisco-decrypt.1: -------------------------------------------------------------------------------- 1 | .TH "CISCO-DECRYPT" "1" "August 2007" "cisco-decrypt" "vpnc" 2 | .SH "NAME" 3 | cisco-decrypt \- decrypts an obfuscated Cisco vpn client pre-shared key 4 | .\" 5 | .\" $Id$ 6 | .\" 7 | .SH "SYNOPSIS" 8 | .B cisco-decrypt 9 | \fI 10 | .SH "DESCRIPTION" 11 | This command accompanies \fBvpnc\fR. It decrypts the obfuscated 12 | pre-shared key from *.pcf\-configuration files, which must be 13 | specified on the command line. 14 | 15 | The result will be printed to STDOUT. 16 | .SH "AUTHOR" 17 | cisco-decrypt was originally written by Maurice Massar. This man\-page was 18 | written by Jörg Mayer, based on the pcf2vpnc manpage written by Wolfram Sang 19 | (ninja(at)the\-dreams.de). 20 | 21 | Permission is granted to copy, distribute and/or modify this document under 22 | the terms of the GNU General Public License, Version 2 any 23 | later version published by the Free Software Foundation. 24 | .PP 25 | On Debian systems, the complete text of the GNU General Public 26 | License can be found in /usr/share/common\-licenses/GPL. 27 | .SH "SEE ALSO" 28 | .BR vpnc(8) 29 | .BR pcf2vpnc(1) 30 | -------------------------------------------------------------------------------- /decrypt-utils.h: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | Copyright (C) 2004-2007 Maurice Massar 3 | A bit reorganized in 2007 by Wolfram Sang 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | 19 | $Id$ 20 | */ 21 | 22 | #ifndef __DECRYPT_UTILS_H__ 23 | #define __DECRYPT_UTILS_H__ 24 | 25 | extern int hex2bin(const char *str, char **bin, int *len); 26 | extern int deobfuscate(char *ct, int len, const char **resp, char *reslenp); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /crypto-openssl.h: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; either version 2 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #ifndef OPENSSL_GPL_VIOLATION 19 | #error "openssl support cannot be built without defining OPENSSL_GPL_VIOLATION" 20 | #endif 21 | 22 | #ifndef __CRYPTO_OPENSSL_H__ 23 | #define __CRYPTO_OPENSSL_H__ 24 | 25 | #include 26 | #include 27 | 28 | typedef struct { 29 | STACK_OF(X509) *stack; 30 | } crypto_ctx; 31 | 32 | #endif /* __CRYPTO_OPENSSL_H__ */ 33 | 34 | -------------------------------------------------------------------------------- /vpnc.h: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | Copyright (C) 2002, 2003, 2004 Geoffrey Keating and Maurice Massar 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | 18 | $Id$ 19 | */ 20 | 21 | #ifndef __VPNC_H__ 22 | #define __VPNC_H__ 23 | 24 | #include "tunip.h" 25 | 26 | void process_late_ike(struct sa_block *s, uint8_t *r_packet, ssize_t r_length); 27 | void keepalive_ike(struct sa_block *s); 28 | void dpd_ike(struct sa_block *s); 29 | void print_vid(const unsigned char *vid, uint16_t len); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /pcf2vpnc.1: -------------------------------------------------------------------------------- 1 | .TH "PCF2VPNC" "1" "June 2007" "pcf2vpnc " "vpnc" 2 | .SH "NAME" 3 | pcf2vpnc \- converts VPN\-config files from pcf to vpnc\-format 4 | .\" 5 | .\" $Id$ 6 | .\" 7 | .SH "SYNOPSIS" 8 | .B pcf2vpnc 9 | \fI \fR[\fIvpnc file\fR] 10 | .SH "DESCRIPTION" 11 | This script accompanies \fBvpnc\fR. It attempts to 12 | convert *.pcf\-configuration files often spread with proprietary 13 | (read Cisco) VPN\-clients into vpnc\-configuration files, 14 | usually named \fB*.conf\fR. 15 | 16 | If [\fIvpnc file\fR] is not specified, the result will be 17 | printed to STDOUT. If specified, it will be written to that 18 | file. Please make sure that it has appropriate permissions as 19 | it may contain sensitive data! 20 | .SH "AUTHOR" 21 | pcf2vpnc was originally written by Stefan Tomanek. Updates and this man\-page were made by Wolfram Sang (ninja(at)the\-dreams.de). 22 | 23 | Permission is granted to copy, distribute and/or modify this document under 24 | the terms of the GNU General Public License, Version 2 any 25 | later version published by the Free Software Foundation. 26 | .PP 27 | On Debian systems, the complete text of the GNU General Public 28 | License can be found in /usr/share/common\-licenses/GPL. 29 | .SH "SEE ALSO" 30 | .BR vpnc(8) 31 | .BR cisco-decrypt(8) 32 | -------------------------------------------------------------------------------- /enum2debug.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | # Usage: ./enum2debug.pl isakmp.h >vpnc-debug.c 2>vpnc-debug.h 4 | 5 | use strict; 6 | use warnings; 7 | 8 | my $in_enum = 0; 9 | 10 | print STDERR << 'EOF'; 11 | /* Automatically generated with enum2debug.pl: Don't edit! */ 12 | 13 | struct debug_strings { 14 | unsigned int id; 15 | const char *string; 16 | }; 17 | 18 | extern const char *val_to_string(unsigned int, const struct debug_strings *); 19 | 20 | EOF 21 | 22 | print << 'EOF'; 23 | /* Automatically generated with enum2debug.pl: Don't edit! */ 24 | 25 | #include 26 | 27 | #include "vpnc-debug.h" 28 | #include "isakmp.h" 29 | 30 | const char *val_to_string(unsigned int val, const struct debug_strings *dstrings) 31 | { 32 | static const char *unknown = " (unknown)"; 33 | static const char *na = ""; 34 | unsigned int i; 35 | 36 | if (dstrings == NULL) 37 | return na; 38 | 39 | for (i = 0; dstrings[i].id != 0 || dstrings[i].string != NULL; i++) 40 | if (dstrings[i].id == val) 41 | return dstrings[i].string; 42 | return unknown; 43 | } 44 | 45 | EOF 46 | 47 | while (<>) { 48 | if (/^enum\W+(\w+)\W*/) { 49 | print STDERR "extern const struct debug_strings $1_array[];\n"; 50 | print "const struct debug_strings $1_array[] = {\n"; 51 | $in_enum = 1; 52 | } elsif ($in_enum && /^}/) { 53 | print "\t{ 0,\t(const char *) 0 }\n};\n\n"; 54 | $in_enum = 0; 55 | } elsif (/^\s*\/\*.*\*\/\s*$/) { 56 | next; 57 | } elsif ($in_enum && /^\W*(\w+)\W*/) { 58 | print "\t{ $1,\t\" ($1)\" },\n"; 59 | } 60 | } 61 | 62 | exit 0; 63 | 64 | __END__ 65 | -------------------------------------------------------------------------------- /supp.h: -------------------------------------------------------------------------------- 1 | /* Algorithm support checks 2 | Copyright (C) 2005 Maurice Massar 3 | Reorganised 2006 by Dan Villiom Podlaski Christiansen 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | 19 | $Id$ 20 | */ 21 | 22 | #ifndef __SUPP_H__ 23 | #define __SUPP_H__ 24 | 25 | enum supp_algo_key { 26 | SUPP_ALGO_NAME, 27 | SUPP_ALGO_MY_ID, 28 | SUPP_ALGO_IKE_SA, 29 | SUPP_ALGO_IPSEC_SA 30 | }; 31 | 32 | enum algo_group { 33 | SUPP_ALGO_DH_GROUP, 34 | SUPP_ALGO_HASH, 35 | SUPP_ALGO_CRYPT, 36 | SUPP_ALGO_AUTH 37 | }; 38 | 39 | typedef struct { 40 | const char *name; 41 | int my_id, ike_sa_id, ipsec_sa_id; 42 | int keylen; 43 | } supported_algo_t; 44 | 45 | extern const supported_algo_t supp_dh_group[]; 46 | extern const supported_algo_t supp_hash[]; 47 | extern const supported_algo_t supp_crypt[]; 48 | extern const supported_algo_t supp_auth[]; 49 | 50 | extern const supported_algo_t *get_algo(enum algo_group what, enum supp_algo_key key, int id, const char *name, int keylen); 51 | extern const supported_algo_t *get_dh_group_ike(void); 52 | extern const supported_algo_t *get_dh_group_ipsec(int server_setting); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /cisco-decrypt.c: -------------------------------------------------------------------------------- 1 | /* Decoder for password encoding of Cisco VPN client. 2 | Copyright (C) 2005 Maurice Massar 3 | 4 | Thanks to HAL-9000@evilscientists.de for decoding and posting the algorithm! 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include "decrypt-utils.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main(int argc, char *argv[]) 29 | { 30 | int i, len, ret = 0; 31 | char *bin, *pw = NULL; 32 | 33 | gcry_check_version(NULL); 34 | 35 | if (argc == 1 || *argv[1] == '-') { 36 | fprintf(stderr, 37 | "\nUsage: %s DEADBEEF...012345678 424242...7261\n" 38 | " Print decoded result to stdout\n\n", 39 | argv[0]); 40 | exit(1); 41 | } 42 | /* Hack for use in pcf2vpnc */ 43 | if (*argv[1] == 'q') { 44 | exit(1); 45 | } 46 | 47 | for (i = 1; i < argc; i++) { 48 | ret = hex2bin(argv[i], &bin, &len); 49 | if (ret != 0) { 50 | perror("decoding input"); 51 | continue; 52 | } 53 | ret = deobfuscate(bin, len, (const char **)&pw, NULL); 54 | free(bin); 55 | if (ret != 0) { 56 | perror("decrypting input"); 57 | continue; 58 | } 59 | printf("%s\n", pw); 60 | free(pw); 61 | } 62 | 63 | exit(ret != 0); 64 | } 65 | -------------------------------------------------------------------------------- /dh.h: -------------------------------------------------------------------------------- 1 | /* borrowed from isakmpd-20030718 (-; */ 2 | 3 | /* $OpenBSD: dh.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */ 4 | /* $EOM: dh.h,v 1.4 1999/04/17 23:20:24 niklas Exp $ */ 5 | 6 | /* 7 | * Copyright (c) 1998 Niels Provos. All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /* 31 | * This code was written under funding by Ericsson Radio Systems. 32 | */ 33 | 34 | #ifndef __DH_H__ 35 | #define __DH_H__ 36 | 37 | #include 38 | 39 | struct group; 40 | 41 | int dh_getlen(struct group *); 42 | int dh_create_exchange(struct group *, unsigned char *); 43 | int dh_create_shared(struct group *, unsigned char *, unsigned char *); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /mk-version: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # print vpnc version from file VERSION, appending the string printed 4 | # by svnversion(1) if appropriate 5 | 6 | in_git_repository () 7 | { 8 | git rev-parse --is-inside-work-tree > /dev/null 2>&1 9 | return $? 10 | } 11 | 12 | git_svn_version () 13 | { 14 | # search for svn-remote defined in git configuration 15 | svn_url_pattern="" 16 | while read key value; do 17 | svn_url_pattern="${svn_url_pattern}\\|${value}" 18 | done << EOF 19 | $(git config --get-regexp '^svn-remote\..*\.url$' 2>/dev/null) 20 | EOF 21 | 22 | # exit if no svn-remote defined 23 | if [ -z "${svn_url_pattern}" ]; then 24 | return 25 | fi 26 | 27 | # scan git-log for latest commit from any svn-remote above 28 | set -- $(git log --first-parent -1 \ 29 | --grep="^git-svn-id: \(${svn_url_pattern#??}\)@" 2>/dev/null) 30 | 31 | # check commit hash is 40 hex digits 32 | svn_commit=$2 33 | if [ ${#svn_commit} -ne 40 -o -z "${svn_commit##*[!0-9a-f]*}" ]; then 34 | return 35 | fi 36 | 37 | # check svn version is numeric 38 | shift $(($# - 2)) 39 | svn_ver=${1#*@} 40 | if [ -z "${svn_ver}" -o -z "${svn_ver##*[!0-9]*}" ]; then 41 | return 42 | fi 43 | 44 | if [ $(git rev-list HEAD...${svn_commit} | wc -l) -eq 0 ]; then 45 | if [ `git status -s | grep -vc '^??'` -eq 0 ]; then 46 | # no git commits and tree clean 47 | echo "${svn_ver}" 48 | return 49 | fi 50 | fi 51 | # there are local git commits after latest svn commit or tree is dirty 52 | echo "${svn_ver}M" 53 | } 54 | 55 | 56 | _version="`cat VERSION`" 57 | 58 | if [ -d .svn ]; then 59 | if which svnversion > /dev/null; then 60 | _version="$_version-`svnversion`" 61 | else 62 | _version="$_version-`sed -n '/^dir$/{n;p;q;}' .svn/entries`" 63 | fi 64 | elif which git > /dev/null && in_git_repository; then 65 | git_ext=$(git_svn_version) 66 | if [ -n "${git_ext}" ]; then 67 | _version="$_version-${git_ext}" 68 | fi 69 | fi 70 | 71 | echo "$_version" 72 | 73 | exit 0 74 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile to rebuild certificate chain for VPNC test. 2 | # Copyright (C) 2013 Antonio Borneo 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 2 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | 18 | OPENSSL = openssl 19 | 20 | CFG = openssl.cnf 21 | TIME = -days 7120 22 | 23 | # default targets empty. 24 | all default clean: 25 | 26 | # target to rebuild everything 27 | rebuild: ca_list.pem cert3.pem sig_data.bin 28 | 29 | ca1.key cert1.key: 30 | $(OPENSSL) genrsa -out $@ 4096 31 | 32 | ca2.key ca3.key cert0.key cert2.key cert3.key: 33 | $(OPENSSL) genrsa -out $@ 2048 34 | 35 | ca1.pem: ca1.key 36 | ca2.pem: ca2.key 37 | ca3.pem: ca3.key 38 | 39 | ca%.pem: ca%.key 40 | $(OPENSSL) req -new -x509 -key $< -out $@ $(TIME) -batch -text \ 41 | -subj "/OU=Root Certification Authority/CN="$@ 42 | 43 | ca_list.pem: ca1.pem ca2.pem ca3.pem 44 | cat $^ > $@ 45 | 46 | CHAIN_SIGN = $(OPENSSL) req -new -key $(2) -batch -subj "/OU=Cert/CN="$(1) \ 47 | | $(OPENSSL) x509 -req $(TIME) -CA $(3) -CAkey $(4) -set_serial 01 \ 48 | -out $(1) -text -extfile $(CFG) -extensions usr 49 | 50 | cert0.pem: cert0.key ca3.pem ca3.key $(CFG) 51 | $(call CHAIN_SIGN,cert0.pem,cert0.key,ca3.pem,ca3.key) 52 | 53 | cert1.pem: cert1.key cert0.pem cert0.key $(CFG) 54 | $(call CHAIN_SIGN,cert1.pem,cert1.key,cert0.pem,cert0.key) 55 | 56 | cert2.pem: cert2.key cert1.pem cert1.key $(CFG) 57 | $(call CHAIN_SIGN,cert2.pem,cert2.key,cert1.pem,cert1.key) 58 | 59 | cert3.pem: cert3.key cert2.pem cert2.key $(CFG) 60 | $(call CHAIN_SIGN,cert3.pem,cert3.key,cert2.pem,cert2.key) 61 | 62 | $(CFG): 63 | echo -e '[ usr ]\nbasicConstraints=CA:TRUE' > $(CFG) 64 | 65 | dec_data.bin: 66 | dd if=/dev/urandom of=$@ bs=256 count=1 67 | 68 | sig_data.bin: dec_data.bin cert0.key 69 | $(OPENSSL) rsautl -decrypt -in $< -out $@ -inkey cert0.key -raw 70 | 71 | clean_build: 72 | rm -f *.pem $(CFG) sig_data.bin 73 | 74 | clean_key: 75 | rm -f *.key dec_data.bin 76 | 77 | clean_all: clean_build clean_key 78 | -------------------------------------------------------------------------------- /test/README.txt: -------------------------------------------------------------------------------- 1 | 2013-12-04: Antonio Borneo 2 | 3 | VPNC includes a wrapper around openssl and gnutls to 4 | offer single set of crypto-API. 5 | The program test-crypto.c is used to verify the API. 6 | 7 | This folder "test" provides a chain of certificates 8 | and an encrypted binary. 9 | test-crypto.c verifies the certificate chain, decrypts 10 | the binary and compare it against expected result. 11 | See below for more details on how to use test-crypto. 12 | 13 | openSSL is required to rebuild the test files. 14 | To avoid the dependence from openSSL during SW compile, 15 | all required files are distribuited together with the 16 | VPNC source code. 17 | 18 | The Makefile in this folder is able to rebuild all the 19 | certificates and the binary. 20 | make clean_all 21 | to cleanup the folder and 22 | make rebuild 23 | to re-build everything from scratch. 24 | Since both cryptographic keys and binary are generated 25 | through random functions, results are not replicable 26 | across executions. Use 27 | make clean_build 28 | if you want to cleanup the folder but keep either keys 29 | and binary file. 30 | 31 | Files in the folder: 32 | - readme.txt: 33 | This file. 34 | - Makefile: 35 | To rebuild all following file. 36 | - ca1.key ca2.key ca3.key: 37 | Pairs of private and public keys, used for 38 | certificate authorities. 39 | - ca1.pem ca2.pem ca3.pem: 40 | Self signed certificate of the certificate 41 | authorities. 42 | - ca_list.pem: 43 | Single file containing all the certificates 44 | of the three CA above. 45 | - cert0.key cert1.key cert2.key cert3.key: 46 | Pairs of private and public keys, used for 47 | certificates. 48 | - cert0.pem cert1.pem cert2.pem cert3.pem: 49 | Certificates derived from ".key" files above. 50 | Certificates are signed in chain: 51 | ca3.pem -> cert0.pem -> cert1.pem -> 52 | -> cert2.pem -> cert3.pem 53 | Self signed certificate "ca3.pem" signs the 54 | certificate "cert0.pem", that in turn signs 55 | "cert1.pem", and so on. 56 | - dec_data.bin: 57 | Binary random data. File size equal to private 58 | key size "cert0.key" (256 byte = 2048 bit). 59 | - sig_data.bin: 60 | Data from "dec_data.bin" RSA encrypted through 61 | private key in "cert0.pem". 62 | - openssl.cnf: 63 | Temporarily config file for openSSL flags that 64 | cannot be passed through command line. 65 | 66 | The program test-crypto.c requires at least 5 arguments: 67 | test-crypto 68 | - is the encrypted binary; 69 | - is the reference binary before encryption; 70 | - is a list of CA certificates, one of them 71 | signs ; 72 | - ... is the chain of certificates. 73 | -------------------------------------------------------------------------------- /dh.c: -------------------------------------------------------------------------------- 1 | /* borrowed from isakmpd-20030718 (-; */ 2 | 3 | /* $OpenBSD: dh.c,v 1.8 2003/06/03 14:28:16 ho Exp $ */ 4 | /* $EOM: dh.c,v 1.5 1999/04/17 23:20:22 niklas Exp $ */ 5 | 6 | /* 7 | * Copyright (c) 1998 Niels Provos. All rights reserved. 8 | * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | /* 32 | * This code was written under funding by Ericsson Radio Systems. 33 | */ 34 | 35 | #include "math_group.h" 36 | #include "dh.h" 37 | 38 | /* 39 | * Returns the length of our exchange value. 40 | */ 41 | 42 | int dh_getlen(struct group *group) 43 | { 44 | return group->getlen(group); 45 | } 46 | 47 | /* 48 | * Creates the exchange value we are offering to the other party. 49 | * Each time this function is called a new value is created, that 50 | * means the application has to save the exchange value itself, 51 | * dh_create_exchange should only be called once. 52 | */ 53 | int dh_create_exchange(struct group *group, unsigned char *buf) 54 | { 55 | if (group->setrandom(group, group->c)) 56 | return -1; 57 | if (group->operation(group, group->a, group->gen, group->c)) 58 | return -1; 59 | group->getraw(group, group->a, buf); 60 | return 0; 61 | } 62 | 63 | /* 64 | * Creates the Diffie-Hellman shared secret in 'secret', where 'exchange' 65 | * is the exchange value offered by the other party. No length verification 66 | * is done for the value, the application has to do that. 67 | */ 68 | int dh_create_shared(struct group *group, unsigned char *secret, unsigned char *exchange) 69 | { 70 | if (group->setraw(group, group->b, exchange, group->getlen(group))) 71 | return -1; 72 | if (group->operation(group, group->a, group->b, group->c)) 73 | return -1; 74 | group->getraw(group, group->a, secret); 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /math_group.h: -------------------------------------------------------------------------------- 1 | /* borrowed from isakmpd-20030718 (-; */ 2 | 3 | /* $OpenBSD: math_group.h,v 1.7 2003/06/03 14:28:16 ho Exp $ */ 4 | /* $EOM: math_group.h,v 1.7 1999/04/17 23:20:40 niklas Exp $ */ 5 | 6 | /* 7 | * Copyright (c) 1998 Niels Provos. All rights reserved. 8 | * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | /* 32 | * This code was written under funding by Ericsson Radio Systems. 33 | */ 34 | 35 | #ifndef __MATH_GROUP_H__ 36 | #define __MATH_GROUP_H__ 37 | 38 | #include 39 | 40 | enum groups { 41 | MODP /* F_p, Z modulo a prime */ 42 | }; 43 | 44 | #define OAKLEY_GRP_1 1 45 | #define OAKLEY_GRP_2 2 46 | #define OAKLEY_GRP_5 3 47 | 48 | /* 49 | * The group on which diffie hellmann calculations are done. 50 | */ 51 | 52 | /* Description of F_p for Boot-Strapping */ 53 | 54 | struct modp_dscr { 55 | int id; 56 | int bits; /* Key Bits provided by this group */ 57 | const char *prime; /* Prime */ 58 | const char *gen; /* Generator */ 59 | }; 60 | 61 | struct modp_group { 62 | gcry_mpi_t gen; /* Generator */ 63 | gcry_mpi_t p; /* Prime */ 64 | gcry_mpi_t a, b, c, d; 65 | }; 66 | 67 | struct group { 68 | enum groups type; 69 | int id; /* Group ID */ 70 | int bits; /* Number of key bits provided by this group */ 71 | struct modp_group *group; 72 | const struct modp_dscr *group_dscr; 73 | void *a, *b, *c, *d; 74 | void *gen; /* Group Generator */ 75 | int (*getlen) (struct group *); 76 | void (*getraw) (struct group *, void *, unsigned char *); 77 | int (*setraw) (struct group *, void *, unsigned char *, int); 78 | int (*setrandom) (struct group *, void *); 79 | int (*operation) (struct group *, void *, void *, void *); 80 | }; 81 | 82 | /* Prototypes */ 83 | 84 | void group_init(void); 85 | void group_free(struct group *); 86 | struct group *group_get(int); 87 | 88 | #endif /* _MATH_GROUP_H_ */ 89 | -------------------------------------------------------------------------------- /decrypt-utils.c: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | Copyright (C) 2004-2007 Maurice Massar 3 | A bit reorganized in 2007 by Wolfram Sang 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | 19 | $Id$ 20 | */ 21 | 22 | #define _GNU_SOURCE 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | #include "decrypt-utils.h" 33 | 34 | 35 | static int hex2bin_c(unsigned int c) 36 | { 37 | if ((c >= '0')&&(c <= '9')) 38 | return c - '0'; 39 | if ((c >= 'A')&&(c <= 'F')) 40 | return c - 'A' + 10; 41 | if ((c >= 'a')&&(c <= 'f')) 42 | return c - 'a' + 10; 43 | return -1; 44 | } 45 | 46 | int hex2bin(const char *str, char **bin, int *len) 47 | { 48 | char *p; 49 | int i, l; 50 | 51 | if (!bin) 52 | return EINVAL; 53 | 54 | for (i = 0; str[i] != '\0'; i++) 55 | if (hex2bin_c(str[i]) == -1) 56 | return EINVAL; 57 | 58 | l = i; 59 | if ((l & 1) != 0) 60 | return EINVAL; 61 | l /= 2; 62 | 63 | p = malloc(l); 64 | if (p == NULL) 65 | return ENOMEM; 66 | 67 | for (i = 0; i < l; i++) 68 | p[i] = hex2bin_c(str[i*2]) << 4 | hex2bin_c(str[i*2+1]); 69 | 70 | *bin = p; 71 | if (len) 72 | *len = l; 73 | 74 | return 0; 75 | } 76 | 77 | int deobfuscate(char *ct, int len, const char **resp, char *reslenp) 78 | { 79 | const char *h1 = ct; 80 | const char *h4 = ct + 20; 81 | const char *enc = ct + 40; 82 | 83 | char ht[20], h2[20], h3[20], key[24]; 84 | const char *iv = h1; 85 | char *res; 86 | gcry_cipher_hd_t ctx; 87 | int reslen; 88 | 89 | if (len < 48) 90 | return -1; 91 | len -= 40; 92 | 93 | memcpy(ht, h1, 20); 94 | 95 | ht[19]++; 96 | gcry_md_hash_buffer(GCRY_MD_SHA1, h2, ht, 20); 97 | 98 | ht[19] += 2; 99 | gcry_md_hash_buffer(GCRY_MD_SHA1, h3, ht, 20); 100 | 101 | memcpy(key, h2, 20); 102 | memcpy(key+20, h3, 4); 103 | /* who cares about parity anyway? */ 104 | 105 | gcry_md_hash_buffer(GCRY_MD_SHA1, ht, enc, len); 106 | 107 | if (memcmp(h4, ht, 20) != 0) 108 | return -1; 109 | 110 | res = malloc(len); 111 | if (res == NULL) 112 | return -1; 113 | 114 | gcry_cipher_open(&ctx, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0); 115 | gcry_cipher_setkey(ctx, key, 24); 116 | gcry_cipher_setiv(ctx, iv, 8); 117 | gcry_cipher_decrypt(ctx, (unsigned char *)res, len, (unsigned char *)enc, len); 118 | gcry_cipher_close(ctx); 119 | 120 | reslen = len - res[len-1]; 121 | res[reslen] = '\0'; 122 | 123 | if (resp) 124 | *resp = res; 125 | if (reslenp) 126 | *reslenp = reslen; 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /vpnc-script-win.js: -------------------------------------------------------------------------------- 1 | // vpnc-script-win.js 2 | // 3 | // Sets up the Network interface and the routes 4 | // needed by vpnc. 5 | 6 | // -------------------------------------------------------------- 7 | // Utilities 8 | // -------------------------------------------------------------- 9 | 10 | function echo(msg) 11 | { 12 | WScript.echo(msg); 13 | } 14 | 15 | function run(cmd) 16 | { 17 | return (ws.Exec(cmd).StdOut.ReadAll()); 18 | } 19 | 20 | function getDefaultGateway() 21 | { 22 | if (run("route print").match(/Default Gateway: *(.*)/)) { 23 | return (RegExp.$1); 24 | } 25 | return (""); 26 | } 27 | 28 | // -------------------------------------------------------------- 29 | // Script starts here 30 | // -------------------------------------------------------------- 31 | 32 | var internal_ip4_netmask = "255.255.255.0" 33 | 34 | var ws = WScript.CreateObject("WScript.Shell"); 35 | var env = ws.Environment("Process"); 36 | 37 | switch (env("reason")) { 38 | case "pre-init": 39 | break; 40 | case "connect": 41 | var gw = getDefaultGateway(); 42 | echo("VPN Gateway: " + env("VPNGATEWAY")); 43 | echo("Internal Address: " + env("INTERNAL_IP4_ADDRESS")); 44 | echo("Internal Netmask: " + env("INTERNAL_IP4_NETMASK")); 45 | echo("Interface: \"" + env("TUNDEV") + "\""); 46 | 47 | if (env("INTERNAL_IP4_NETMASK")) { 48 | internal_ip4_netmask = env("INTERNAL_IP4_NETMASK"); 49 | } 50 | 51 | echo("Configuring \"" + env("TUNDEV") + "\" interface..."); 52 | run("netsh interface ip set address \"" + env("TUNDEV") + "\" static " + 53 | env("INTERNAL_IP4_ADDRESS") + " " + internal_ip4_netmask); 54 | 55 | // Add direct route for the VPN gateway to avoid routing loops 56 | run("route add " + env("VPNGATEWAY") + 57 | " mask 255.255.255.255 " + gw); 58 | 59 | if (env("INTERNAL_IP4_NBNS")) { 60 | var wins = env("INTERNAL_IP4_NBNS").split(/ /); 61 | for (var i = 0; i < wins.length; i++) { 62 | run("netsh interface ip add wins \"" + 63 | env("TUNDEV") + "\" " + wins[i] 64 | + " index=" + (i+1)); 65 | } 66 | } 67 | 68 | if (env("INTERNAL_IP4_DNS")) { 69 | var dns = env("INTERNAL_IP4_DNS").split(/ /); 70 | for (var i = 0; i < dns.length; i++) { 71 | run("netsh interface ip add dns \"" + 72 | env("TUNDEV") + "\" " + dns[i] 73 | + " index=" + (i+1)); 74 | } 75 | } 76 | echo("done."); 77 | 78 | // Add internal network routes 79 | echo("Configuring networks:"); 80 | if (env("CISCO_SPLIT_INC")) { 81 | for (var i = 0 ; i < parseInt(env("CISCO_SPLIT_INC")); i++) { 82 | var network = env("CISCO_SPLIT_INC_" + i + "_ADDR"); 83 | var netmask = env("CISCO_SPLIT_INC_" + i + "_MASK"); 84 | var netmasklen = env("CISCO_SPLIT_INC_" + i + 85 | "_MASKLEN"); 86 | run("route add " + network + " mask " + netmask + 87 | " " + env("INTERNAL_IP4_ADDRESS")); 88 | } 89 | } else { 90 | echo("Gateway did not provide network configuration."); 91 | } 92 | echo("Route configuration done."); 93 | 94 | if (env("CISCO_BANNER")) { 95 | echo("--------------------------------------------------"); 96 | echo(env("CISCO_BANNER")); 97 | echo("--------------------------------------------------"); 98 | } 99 | break; 100 | case "disconnect": 101 | // Delete direct route for the VPN gateway to avoid 102 | run("route delete " + env("VPNGATEWAY") + " mask 255.255.255.255"); 103 | } 104 | 105 | -------------------------------------------------------------------------------- /nortel.txt: -------------------------------------------------------------------------------- 1 | [vpnc-devel] vpnc with Nortel Contivity 2 | 3 | Matt Chapman 4 | Thu Jun 9 21:51:50 CEST 2005 5 | 6 | 7 | I've managed to get vpnc working with a Nortel Contivity VPN 8 | concentrator. 9 | 10 | Basically the differences are: 11 | 12 | * The group name and password are pre-transformed: 13 | key_id = SHA1(group_name) 14 | shared_key = HMAC_SHA1(group_name, SHA1(group_password)) 15 | 16 | * The XAUTH implementation follows 17 | draft-ietf-ipsec-isakmp-xauth-02.txt (whereas CISCO uses a 18 | later version). Specifically: 19 | - the encoding of the proposal is not defined in that spec, 20 | and Nortel does it differently 21 | - the XAUTH attributes have different numerical values 22 | (which overlap with Mode-Config, argh) 23 | - success/failure are encoded as Mode-Config message types 24 | 5/6 (or sometimes as an ISAKMP notify?) rather than in 25 | an attribute 26 | - the concentrator always sends 0 in XAUTH_TYPE and the 27 | client may have to return a different value (xauth-02 is 28 | not clear on whether this is allowed, it is not 29 | clarified until xauth-05). In my case I'm using an 30 | ActivCard token for which I have to specify 5 (SecurID). 31 | 32 | * Mode-Config is done as a push, i.e. the server sends SET, 33 | instead of a pull. 34 | 35 | * The concentrator wants to be the initiator in phase 2 36 | quick mode, so we have to support being a responder. 37 | 38 | Thus the changes are fairly intrusive - phase 1 is common 39 | but XAUTH/Mode-Config/phase 2 diverge. 40 | 41 | If people are interested, I can clean up what I've done 42 | and send patches. 43 | 44 | Matt 45 | ---------------- 46 | I've tried to connect to my corporate VPN, but the only message I got was: 47 | 48 | vpnc: xauth packet unsupported: ATTRIBUTES_NOT_SUPPORTED 49 | 50 | Problem was found in xauth_type. In my case request attribute "xauth_type" consisted 5 as value. There is quick 51 | fix for this issue below. But... 52 | 53 | In the chapter 6.2 of the draft-beaulieu-ike-xauth-02.txt we can read: 54 | 55 | "XAUTH-TYPE - The type of extended authentication requested whose 56 | values are described in the next section. This is an optional 57 | attribute for the ISAKMP_CFG_REQUEST and ISAKMP_CFG_REPLY messages. 58 | If the XAUTH-TYPE is not present, then it is assumed to be Generic. 59 | The XAUTH-TYPE in a REPLY MUST be identical to the XAUTH-TYPE in the 60 | REQUEST." 61 | 62 | So I think the better way is to send reply with the same xauth_type value as in request. But I can't test it 63 | because our server always use 5 and never 0. 64 | 65 | Thanks. 66 | ---- 67 | Volodymyr Buell 68 | 69 | ------------ This ended up in the folowin patch 70 | if (ap->af != isakmp_attr_16 || !(ap->u.attr_16 == 0 || ap->u.attr_16 == 5)) 71 | reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED; 72 | xauth_type_requested = ap->u.attr_16; 73 | ---------------------- 74 | 75 | This patch didn't work in my NortelVPN setup I mad a buildflag of until a proper fix can be made 76 | so please set NORTELVPN_XAUTHTYPE_AS_REQUEST flag to vpnc.c to get this 77 | 78 | #ifdef NORTELVPN_XAUTHTYPE_AS_REQUEST 79 | if (ap->af != isakmp_attr_16 || !(ap->u.attr_16 == 0 || ap->u.attr_16 == 5)) 80 | reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED; 81 | xauth_type_requested = ap->u.attr_16; 82 | #else 83 | 84 | if (ap->af != isakmp_attr_16 || ap->u.attr_16 != 0) 85 | reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED; 86 | #endif 87 | 88 | 89 | /Zingo Andersen -------------------------------------------------------------------------------- /tap-win32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file has been borrowed from the Win32 OpenVPN Tap driver 3 | * (common.h is the original file name). 4 | * 5 | * TAP-Win32 -- A kernel driver to provide virtual tap device functionality 6 | * on Windows. Originally derived from the CIPE-Win32 7 | * project by Damion K. Wilson, with extensive modifications by 8 | * James Yonan. 9 | * 10 | * All source code which derives from the CIPE-Win32 project is 11 | * Copyright (C) Damion K. Wilson, 2003, and is released under the 12 | * GPL version 2 (see below). 13 | * 14 | * All other source code is Copyright (C) 2002-2005 OpenVPN Solutions LLC, 15 | * and is released under the GPL version 2 (see below). 16 | * 17 | * This program is free software; you can redistribute it and/or modify 18 | * it under the terms of the GNU General Public License version 2 19 | * as published by the Free Software Foundation. 20 | * 21 | * This program is distributed in the hope that it will be useful, 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | * GNU General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU General Public License 27 | * along with this program (see the file COPYING included with this 28 | * distribution); if not, write to the Free Software Foundation, Inc., 29 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30 | */ 31 | 32 | /* =============================================== 33 | This file is included both by OpenVPN and 34 | the TAP-Win32 driver and contains definitions 35 | common to both. 36 | =============================================== */ 37 | 38 | /* ============= 39 | TAP IOCTLs 40 | ============= */ 41 | 42 | #define TAP_CONTROL_CODE(request,method) \ 43 | CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) 44 | 45 | /* Present in 8.1 */ 46 | 47 | #define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) 48 | #define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) 49 | #define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) 50 | #define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) 51 | #define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) 52 | #define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) 53 | #define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) 54 | #define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) 55 | #define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) 56 | 57 | /* Added in 8.2 */ 58 | 59 | /* obsoletes TAP_IOCTL_CONFIG_POINT_TO_POINT */ 60 | #define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE (10, METHOD_BUFFERED) 61 | 62 | /* ================= 63 | Registry keys 64 | ================= */ 65 | 66 | #define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 67 | 68 | #define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 69 | 70 | /* ====================== 71 | Filesystem prefixes 72 | ====================== */ 73 | 74 | #define USERMODEDEVICEDIR "\\\\.\\Global\\" 75 | #define SYSDEVICEDIR "\\Device\\" 76 | #define USERDEVICEDIR "\\DosDevices\\Global\\" 77 | #define TAPSUFFIX ".tap" 78 | 79 | /* ========================================================= 80 | TAP_COMPONENT_ID -- These strings defines the TAP driver 81 | types -- different component IDs can reside in the system 82 | simultaneously. 83 | ========================================================= */ 84 | 85 | static const char* TAP_COMPONENT_ID[] = { "tap0901", "tap0801", NULL }; 86 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | Copyright (C) 2004-2005 Maurice Massar 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | 18 | $Id$ 19 | */ 20 | 21 | #ifndef __CONFIG_H__ 22 | #define __CONFIG_H__ 23 | 24 | #include 25 | #include 26 | 27 | #include "vpnc-debug.h" 28 | 29 | enum config_enum { 30 | CONFIG_SCRIPT, 31 | CONFIG_DEBUG, 32 | CONFIG_DOMAIN, 33 | CONFIG_ENABLE_1DES, 34 | CONFIG_ENABLE_NO_ENCRYPTION, 35 | CONFIG_ND, 36 | CONFIG_NON_INTERACTIVE, 37 | CONFIG_PID_FILE, 38 | CONFIG_LOCAL_ADDR, 39 | CONFIG_LOCAL_PORT, 40 | CONFIG_VERSION, 41 | CONFIG_IF_NAME, 42 | CONFIG_IF_MODE, 43 | CONFIG_IF_MTU, 44 | CONFIG_IKE_DH, 45 | CONFIG_IPSEC_PFS, 46 | CONFIG_IPSEC_GATEWAY, 47 | CONFIG_IPSEC_TARGET_NETWORK, 48 | CONFIG_IPSEC_ID, 49 | CONFIG_IPSEC_SECRET, 50 | CONFIG_IPSEC_SECRET_OBF, 51 | CONFIG_XAUTH_USERNAME, 52 | CONFIG_XAUTH_PASSWORD, 53 | CONFIG_XAUTH_PASSWORD_OBF, 54 | CONFIG_XAUTH_INTERACTIVE, 55 | CONFIG_VENDOR, 56 | CONFIG_NATT_MODE, 57 | CONFIG_UDP_ENCAP_PORT, 58 | CONFIG_DPD_IDLE, 59 | CONFIG_AUTH_MODE, 60 | CONFIG_CA_FILE, 61 | CONFIG_CA_DIR, 62 | CONFIG_PASSWORD_HELPER, 63 | LAST_CONFIG 64 | }; 65 | 66 | enum hex_dump_enum { 67 | DUMP_UINT8 = -1, 68 | DUMP_UINT16 = -2, 69 | DUMP_UINT32 = -4 70 | }; 71 | 72 | enum vendor_enum { 73 | VENDOR_CISCO, 74 | VENDOR_NETSCREEN 75 | }; 76 | 77 | enum natt_mode_enum { 78 | NATT_NONE, 79 | NATT_NORMAL, 80 | NATT_FORCE, 81 | NATT_CISCO_UDP 82 | }; 83 | 84 | enum if_mode_enum { 85 | IF_MODE_TUN, 86 | IF_MODE_TAP 87 | }; 88 | 89 | enum auth_mode_enum { 90 | AUTH_MODE_PSK, 91 | AUTH_MODE_RSA1, 92 | AUTH_MODE_RSA2, 93 | AUTH_MODE_CERT, 94 | AUTH_MODE_HYBRID 95 | }; 96 | 97 | extern const char *config[LAST_CONFIG]; 98 | 99 | extern enum vendor_enum opt_vendor; 100 | extern int opt_debug; 101 | extern int opt_nd; 102 | extern int opt_1des, opt_no_encryption, opt_auth_mode; 103 | extern enum natt_mode_enum opt_natt_mode; 104 | extern enum if_mode_enum opt_if_mode; 105 | extern uint16_t opt_udpencapport; 106 | 107 | #define TIMESTAMP() ({ \ 108 | char st[20]; \ 109 | time_t t; \ 110 | struct tm *tm; \ 111 | t = time(NULL); \ 112 | tm = localtime(&t); \ 113 | strftime(st, sizeof(st), "%F %T", tm); \ 114 | st; \ 115 | }) 116 | 117 | #define DEBUGTOP(LVL, COMMAND) do { \ 118 | if (opt_debug >= (LVL)) { \ 119 | printf("\n"); \ 120 | COMMAND; \ 121 | printf(" [%s]\n", TIMESTAMP()); \ 122 | } \ 123 | } while (0) 124 | 125 | #define DEBUG(LVL, COMMAND) do { \ 126 | if (opt_debug >= (LVL)) { \ 127 | if (opt_debug > 1) \ 128 | printf(" "); \ 129 | COMMAND; \ 130 | } \ 131 | } while (0) 132 | 133 | extern void hex_dump(const char *str, const void *data, ssize_t len, const struct debug_strings *decode); 134 | extern void do_config(int argc, char **argv); 135 | extern char *vpnc_getpass(const char *prompt); 136 | 137 | extern void (*logmsg)(int priority, const char *format, ...) 138 | __attribute__ ((__format__ (__printf__, 2, 3))); 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /test/cert3.pem: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 1 (0x1) 5 | Signature Algorithm: sha1WithRSAEncryption 6 | Issuer: OU=Cert, CN=cert2.pem 7 | Validity 8 | Not Before: Dec 4 13:26:13 2013 GMT 9 | Not After : Jun 2 13:26:13 2033 GMT 10 | Subject: OU=Cert, CN=cert3.pem 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | Public-Key: (2048 bit) 14 | Modulus: 15 | 00:b3:9c:7b:17:41:6c:2f:57:f1:b0:e8:a5:5f:0c: 16 | c6:65:15:cc:b1:68:c4:39:bd:9d:b0:14:92:39:b7: 17 | e4:5d:c7:4d:33:33:67:7f:11:fd:0c:d5:c2:bb:15: 18 | 10:bb:42:c6:c5:80:0d:0e:4e:a5:2e:c1:2b:9c:15: 19 | 2d:59:51:88:34:89:fb:4e:19:be:17:c9:66:04:7f: 20 | 11:72:5a:75:44:04:dd:82:51:0d:b8:01:df:09:a2: 21 | fb:d9:64:9e:21:38:fd:a7:84:fd:62:62:a7:0f:c2: 22 | 94:16:c5:75:5e:d4:f8:31:e2:55:f5:3c:9a:af:b5: 23 | 73:21:d6:52:99:7f:da:f2:24:ed:ea:e9:79:59:83: 24 | c4:32:3b:23:06:90:c2:b1:ba:b3:00:2e:47:2e:e3: 25 | 82:c0:59:fd:2d:72:e1:8a:ba:ed:a8:b5:f2:59:eb: 26 | 23:2d:e9:aa:42:ff:75:92:43:ac:e2:15:d6:69:13: 27 | aa:eb:4c:9d:59:07:83:d9:dd:ac:57:f7:35:10:52: 28 | a3:41:c9:03:07:d9:1f:32:18:f6:c1:2a:84:f0:5f: 29 | 11:15:77:7f:30:e0:fb:18:fe:d0:bb:00:bb:54:16: 30 | a0:47:89:fa:67:07:4e:15:91:64:20:e1:05:89:66: 31 | f6:3c:3b:e9:90:37:5b:e3:d5:3f:3e:a4:83:d4:bf: 32 | e9:23 33 | Exponent: 65537 (0x10001) 34 | X509v3 extensions: 35 | X509v3 Basic Constraints: 36 | CA:TRUE 37 | Signature Algorithm: sha1WithRSAEncryption 38 | 05:8d:41:b5:b8:7f:d5:38:97:01:3f:f9:5d:83:9e:ca:54:9f: 39 | ff:91:04:83:6b:9f:5f:27:be:c2:b7:4b:b7:ec:f8:11:28:14: 40 | a6:b4:59:8d:7d:57:10:b4:08:04:56:ff:c9:63:32:db:6a:b2: 41 | 28:db:28:27:84:c9:53:e0:de:4c:45:b4:01:37:2d:27:06:41: 42 | 1f:85:d6:65:c6:a3:21:3c:a0:eb:e6:20:2b:c5:49:57:f2:e4: 43 | 27:c9:20:c7:dd:8e:3b:53:f1:17:2b:52:f1:b2:70:e6:ed:c5: 44 | 5a:4c:df:24:16:96:d6:20:41:51:1b:b1:af:c5:39:44:6c:dd: 45 | b7:3a:16:05:06:89:a5:c8:c8:18:03:98:5a:3e:1f:22:44:e5: 46 | 68:fb:be:3e:37:43:52:03:f8:9e:21:cb:1e:29:4f:0a:ff:33: 47 | 0f:86:3b:b5:a4:33:73:89:a9:07:91:3e:e5:41:97:d4:46:c0: 48 | 98:43:9e:bc:d9:f2:4a:1f:b3:52:9b:48:7e:7c:31:39:d4:9c: 49 | 77:bb:78:27:9b:32:56:9b:b2:b8:0d:e3:ea:c7:c1:03:d0:29: 50 | 46:a9:b3:b8:62:d9:91:26:a6:af:b8:c2:3e:28:e7:a0:dd:f4: 51 | 06:1c:75:0f:f5:9f:52:b0:51:fc:f9:41:ec:3e:2d:95:dc:ab: 52 | 7c:bc:0a:d5 53 | -----BEGIN CERTIFICATE----- 54 | MIIC0TCCAbmgAwIBAgIBATANBgkqhkiG9w0BAQUFADAjMQ0wCwYDVQQLDARDZXJ0 55 | MRIwEAYDVQQDDAljZXJ0Mi5wZW0wHhcNMTMxMjA0MTMyNjEzWhcNMzMwNjAyMTMy 56 | NjEzWjAjMQ0wCwYDVQQLDARDZXJ0MRIwEAYDVQQDDAljZXJ0My5wZW0wggEiMA0G 57 | CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCznHsXQWwvV/Gw6KVfDMZlFcyxaMQ5 58 | vZ2wFJI5t+Rdx00zM2d/Ef0M1cK7FRC7QsbFgA0OTqUuwSucFS1ZUYg0iftOGb4X 59 | yWYEfxFyWnVEBN2CUQ24Ad8JovvZZJ4hOP2nhP1iYqcPwpQWxXVe1Pgx4lX1PJqv 60 | tXMh1lKZf9ryJO3q6XlZg8QyOyMGkMKxurMALkcu44LAWf0tcuGKuu2otfJZ6yMt 61 | 6apC/3WSQ6ziFdZpE6rrTJ1ZB4PZ3axX9zUQUqNByQMH2R8yGPbBKoTwXxEVd38w 62 | 4PsY/tC7ALtUFqBHifpnB04VkWQg4QWJZvY8O+mQN1vj1T8+pIPUv+kjAgMBAAGj 63 | EDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWNQbW4f9U4lwE/ 64 | +V2DnspUn/+RBINrn18nvsK3S7fs+BEoFKa0WY19VxC0CARW/8ljMttqsijbKCeE 65 | yVPg3kxFtAE3LScGQR+F1mXGoyE8oOvmICvFSVfy5CfJIMfdjjtT8RcrUvGycObt 66 | xVpM3yQWltYgQVEbsa/FOURs3bc6FgUGiaXIyBgDmFo+HyJE5Wj7vj43Q1ID+J4h 67 | yx4pTwr/Mw+GO7WkM3OJqQeRPuVBl9RGwJhDnrzZ8kofs1KbSH58MTnUnHe7eCeb 68 | MlabsrgN4+rHwQPQKUaps7hi2ZEmpq+4wj4o56Dd9AYcdQ/1n1KwUfz5Qew+LZXc 69 | q3y8CtU= 70 | -----END CERTIFICATE----- 71 | -------------------------------------------------------------------------------- /crypto.c: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; either version 2 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "sysdep.h" 29 | #include "crypto.h" 30 | 31 | 32 | #define MSG_SIZE 200 33 | void crypto_error_set(crypto_error **error, 34 | int code, 35 | int in_errno, 36 | const char *fmt, ...) 37 | { 38 | va_list args; 39 | 40 | if (!error) 41 | return; 42 | if (*error) { 43 | fprintf(stderr, "%s: called with non-NULL *error\n", __func__); 44 | return; 45 | } 46 | 47 | *error = calloc(1, sizeof(crypto_error)); 48 | if (!*error) 49 | return; 50 | 51 | (*error)->code = code; 52 | (*error)->err = in_errno; 53 | 54 | (*error)->msg = malloc(MSG_SIZE); 55 | if (!(*error)->msg) { 56 | fprintf(stderr, "%s: not enough memory for error message\n", __func__); 57 | crypto_error_clear(error); 58 | return; 59 | } 60 | 61 | va_start(args, fmt); 62 | if (vsnprintf((*error)->msg, MSG_SIZE, fmt, args) == -1) 63 | (*error)->msg[0] = '\0'; 64 | va_end(args); 65 | } 66 | 67 | void crypto_error_free(crypto_error *error) 68 | { 69 | if (error) { 70 | if (error->msg) 71 | free(error->msg); 72 | memset(error, 0, sizeof(crypto_error)); 73 | free(error); 74 | } 75 | } 76 | 77 | void crypto_error_clear(crypto_error **error) 78 | { 79 | if (error && *error) { 80 | crypto_error_free(*error); 81 | *error = NULL; 82 | } 83 | } 84 | 85 | void crypto_call_error(crypto_error *err) 86 | { 87 | if (err) 88 | error(err->code, err->err, "%s\n", err->msg); 89 | else 90 | error(1, 0, "unknown error"); 91 | } 92 | 93 | unsigned char * 94 | crypto_read_file(const char *path, size_t *out_len, crypto_error **error) 95 | { 96 | struct stat st; 97 | int fd; 98 | ssize_t bytes_read; 99 | size_t file_size; 100 | unsigned char *data = NULL; 101 | 102 | *out_len = 0; 103 | 104 | fd = open(path, O_RDONLY); 105 | if (fd < 0) { 106 | crypto_error_set(error, 1, errno, "failed to open file '%s'", path); 107 | return NULL; 108 | } 109 | 110 | if (fstat(fd, &st) < 0) { 111 | crypto_error_set(error, 1, errno, "failed to stat file '%s'", path); 112 | goto out; 113 | } 114 | 115 | if (st.st_size <= 0 || st.st_size > INT_MAX) { 116 | crypto_error_set(error, 1, errno, "invalid file '%s' length %ld", path, st.st_size); 117 | goto out; 118 | } 119 | 120 | file_size = st.st_size; 121 | data = malloc(file_size); 122 | if (!data) { 123 | crypto_error_set(error, 1, ENOMEM, "not enough memory to read file '%s'", path); 124 | goto out; 125 | } 126 | 127 | do { 128 | bytes_read = read(fd, &(data[*out_len]), (st.st_size - *out_len)); 129 | if (bytes_read < 0) { 130 | free(data); 131 | data = NULL; 132 | *out_len = 0; 133 | crypto_error_set(error, 1, errno, "failed to read file '%s'", path); 134 | goto out; 135 | } 136 | *out_len += bytes_read; 137 | } while ((bytes_read > 0) && (*out_len <= file_size)); 138 | 139 | out: 140 | close(fd); 141 | return data; 142 | } 143 | 144 | -------------------------------------------------------------------------------- /tunip.h: -------------------------------------------------------------------------------- 1 | /* IPSec ESP and AH support. 2 | Copyright (C) 2005 Maurice Massar 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | 18 | $Id$ 19 | */ 20 | 21 | #ifndef __TUNIP_H__ 22 | #define __TUNIP_H__ 23 | 24 | #include "isakmp.h" 25 | 26 | #include 27 | #include 28 | 29 | struct lifetime { 30 | time_t start; 31 | uint32_t seconds; 32 | uint32_t kbytes; 33 | uint32_t rx; 34 | uint32_t tx; 35 | }; 36 | 37 | struct ike_sa { 38 | uint32_t spi; 39 | uint32_t seq_id; /* for replay protection (not implemented) */ 40 | 41 | uint8_t *key; 42 | uint8_t *key_cry; 43 | gcry_cipher_hd_t cry_ctx; 44 | uint8_t *key_md; 45 | 46 | /* Description of the packet being processed */ 47 | unsigned char *buf; 48 | unsigned int bufsize, bufpayload, var_header_size; 49 | int buflen; 50 | }; 51 | 52 | struct encap_method; /* private to tunip.c */ 53 | 54 | enum natt_active_mode_enum{ 55 | NATT_ACTIVE_NONE, 56 | NATT_ACTIVE_CISCO_UDP, /* isakmp and esp on different ports => never encap */ 57 | NATT_ACTIVE_DRAFT_OLD, /* as in natt-draft 0 and 1 */ 58 | NATT_ACTIVE_RFC /* draft 2 and RFC3947 / RFC3948 */ 59 | }; 60 | 61 | struct sa_block { 62 | const char *pidfile; 63 | 64 | int tun_fd; /* fd to host via tun/tap */ 65 | char tun_name[IFNAMSIZ]; 66 | uint8_t tun_hwaddr[ETH_ALEN]; 67 | 68 | struct in_addr dst; /* ip of concentrator, must be set */ 69 | struct in_addr src; /* local ip, from getsockname() */ 70 | 71 | struct in_addr opt_src_ip; /* configured local ip, can be 0.0.0.0 */ 72 | 73 | /* these sockets are connect()ed */ 74 | int ike_fd; /* fd over isakmp traffic, and in case of NAT-T esp too */ 75 | int esp_fd; /* raw socket for ip-esp or Cisco-UDP or ike_fd (NAT-T) */ 76 | 77 | struct { 78 | int timeout; 79 | uint8_t *resend_hash; 80 | uint16_t src_port, dst_port; 81 | uint8_t i_cookie[ISAKMP_COOKIE_LENGTH]; 82 | uint8_t r_cookie[ISAKMP_COOKIE_LENGTH]; 83 | uint8_t *key; /* ike encryption key */ 84 | size_t keylen; 85 | uint8_t *initial_iv; 86 | uint8_t *skeyid_a; 87 | uint8_t *skeyid_d; 88 | int auth_algo; /* PSK, PSK+Xauth, Hybrid ToDo: Cert/... */ 89 | int cry_algo, md_algo; 90 | size_t ivlen, md_len; 91 | uint8_t current_iv_msgid[4]; 92 | uint8_t *current_iv; 93 | struct lifetime life; 94 | int do_dpd; 95 | int dpd_idle; 96 | uint32_t dpd_seqno; 97 | uint32_t dpd_seqno_ack; 98 | time_t dpd_sent; 99 | unsigned int dpd_attempts; 100 | uint8_t *psk_hash; 101 | uint8_t *sa_f, *idi_f; 102 | size_t sa_size, idi_size; 103 | uint8_t *dh_public; 104 | struct group *dh_grp; 105 | uint8_t i_nonce[20]; 106 | uint8_t *returned_hash; 107 | int natd_type; 108 | uint8_t *natd_us, *natd_them; 109 | } ike; 110 | struct in_addr our_address; 111 | struct { 112 | int do_pfs; 113 | int cry_algo, md_algo; 114 | size_t key_len, md_len; 115 | size_t blk_len, iv_len; 116 | uint16_t encap_mode; 117 | uint16_t peer_udpencap_port; 118 | enum natt_active_mode_enum natt_active_mode; 119 | struct lifetime life; 120 | struct ike_sa rx, tx; 121 | struct encap_method *em; 122 | uint16_t ip_id; 123 | } ipsec; 124 | }; 125 | 126 | extern int volatile do_kill; 127 | extern void vpnc_doit(struct sa_block *s); 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /test/cert0.pem: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 1 (0x1) 5 | Signature Algorithm: sha1WithRSAEncryption 6 | Issuer: OU=Root Certification Authority, CN=ca3.pem 7 | Validity 8 | Not Before: Dec 4 13:26:13 2013 GMT 9 | Not After : Jun 2 13:26:13 2033 GMT 10 | Subject: OU=Cert, CN=cert0.pem 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | Public-Key: (2048 bit) 14 | Modulus: 15 | 00:bf:6d:e1:6a:22:df:a9:d1:75:d7:4e:8f:a1:cf: 16 | 81:3b:83:9f:35:2b:ea:a1:37:ba:37:9f:45:fc:67: 17 | 44:88:25:34:32:e7:79:8f:bf:6b:9f:68:ee:9a:38: 18 | c1:ea:ce:52:d6:b4:74:4f:a9:80:d0:3e:66:24:3f: 19 | 90:d0:86:7b:b3:40:ea:38:22:19:21:a1:dc:d8:ee: 20 | 39:80:66:af:fc:47:ad:30:e1:a7:c9:fe:9c:58:aa: 21 | 86:98:96:41:48:16:01:e5:0b:71:c3:d0:10:79:94: 22 | 50:e6:49:74:f9:8f:77:34:cc:a0:dd:a5:7b:b5:d3: 23 | 9d:d6:1f:71:5a:42:68:6d:9b:54:40:ad:f0:45:5e: 24 | 48:e3:07:ad:08:23:91:2c:01:f9:08:b5:53:f7:f2: 25 | 07:d9:89:41:ba:85:45:48:98:b9:7e:fe:47:6d:55: 26 | f6:11:c5:20:55:cc:da:fb:d8:92:62:02:16:31:d3: 27 | 18:fb:b0:93:40:5a:78:17:51:fe:62:2e:68:fb:d9: 28 | 3f:f3:20:9a:ea:28:fc:1d:28:be:8d:1c:34:2b:07: 29 | 47:17:5f:c6:97:df:72:1c:88:a0:02:37:13:0e:44: 30 | c1:7c:db:dd:8e:a9:59:54:a6:46:4b:c8:d8:03:39: 31 | 6e:15:31:a8:d6:9b:8d:72:89:6b:4b:eb:9d:26:14: 32 | 37:47 33 | Exponent: 65537 (0x10001) 34 | X509v3 extensions: 35 | X509v3 Basic Constraints: 36 | CA:TRUE 37 | Signature Algorithm: sha1WithRSAEncryption 38 | 99:8f:67:14:00:32:06:9b:bf:42:31:92:5d:bf:02:a0:b0:e6: 39 | 67:11:c2:37:89:29:84:db:20:00:10:55:bf:14:31:1b:32:e9: 40 | e5:26:4f:c1:52:81:66:6c:92:02:c1:32:69:27:22:b0:72:d5: 41 | 62:d0:3e:93:91:b7:c3:8b:0e:e9:8c:c1:d9:d7:59:b1:ca:1e: 42 | f2:11:bb:e9:4f:2f:e6:45:05:4c:30:9e:c2:59:07:ff:e5:e6: 43 | 8c:d9:63:ae:12:e2:55:d9:9b:99:7b:0e:1d:96:bc:b0:5b:d9: 44 | 10:e7:f6:06:45:a0:66:c8:fa:2d:df:c0:5b:73:98:ee:bb:82: 45 | 8b:ad:67:70:98:6b:2c:a3:ad:4a:a6:79:18:81:3c:2b:dc:79: 46 | f4:de:aa:d4:fe:3e:b3:fc:32:12:45:9a:90:48:70:e2:ed:65: 47 | b2:59:1d:1c:c2:3a:e3:2d:0d:4b:3c:33:23:1d:80:9b:8b:1c: 48 | d1:48:5d:c3:6e:58:49:7a:b3:4b:70:86:a5:31:b0:e6:d5:82: 49 | 07:3c:6f:43:60:f1:b3:b4:39:7c:40:45:d7:a8:0c:5f:81:a5: 50 | c6:86:14:59:0e:6c:b2:88:05:7a:85:ef:6f:5c:e7:a1:89:c9: 51 | 29:95:5f:ba:7e:03:e4:66:d4:11:23:9c:9f:72:f8:00:b2:5c: 52 | a0:46:09:e8 53 | -----BEGIN CERTIFICATE----- 54 | MIIC5zCCAc+gAwIBAgIBATANBgkqhkiG9w0BAQUFADA5MSUwIwYDVQQLDBxSb290 55 | IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRAwDgYDVQQDDAdjYTMucGVtMB4XDTEz 56 | MTIwNDEzMjYxM1oXDTMzMDYwMjEzMjYxM1owIzENMAsGA1UECwwEQ2VydDESMBAG 57 | A1UEAwwJY2VydDAucGVtMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA 58 | v23haiLfqdF1106Poc+BO4OfNSvqoTe6N59F/GdEiCU0Mud5j79rn2jumjjB6s5S 59 | 1rR0T6mA0D5mJD+Q0IZ7s0DqOCIZIaHc2O45gGav/EetMOGnyf6cWKqGmJZBSBYB 60 | 5Qtxw9AQeZRQ5kl0+Y93NMyg3aV7tdOd1h9xWkJobZtUQK3wRV5I4wetCCORLAH5 61 | CLVT9/IH2YlBuoVFSJi5fv5HbVX2EcUgVcza+9iSYgIWMdMY+7CTQFp4F1H+Yi5o 62 | +9k/8yCa6ij8HSi+jRw0KwdHF1/Gl99yHIigAjcTDkTBfNvdjqlZVKZGS8jYAzlu 63 | FTGo1puNcolrS+udJhQ3RwIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 64 | DQEBBQUAA4IBAQCZj2cUADIGm79CMZJdvwKgsOZnEcI3iSmE2yAAEFW/FDEbMunl 65 | Jk/BUoFmbJICwTJpJyKwctVi0D6TkbfDiw7pjMHZ11mxyh7yEbvpTy/mRQVMMJ7C 66 | WQf/5eaM2WOuEuJV2ZuZew4dlrywW9kQ5/YGRaBmyPot38Bbc5juu4KLrWdwmGss 67 | o61KpnkYgTwr3Hn03qrU/j6z/DISRZqQSHDi7WWyWR0cwjrjLQ1LPDMjHYCbixzR 68 | SF3DblhJerNLcIalMbDm1YIHPG9DYPGztDl8QEXXqAxfgaXGhhRZDmyyiAV6he9v 69 | XOehickplV+6fgPkZtQRI5yfcvgAslygRgno 70 | -----END CERTIFICATE----- 71 | -------------------------------------------------------------------------------- /pcf2vpnc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # Stefan Tomanek 3 | # updated by Wolfram Sang on 21.10.06 and on 26.06.07 4 | ## 5 | # pcf2vpnc [vpnc file] 6 | ## 7 | # This program is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # $Id$ 22 | 23 | use IO::File; 24 | use strict; 25 | use warnings; 26 | 27 | my %authmode = ( 1 => 'psk', 3 => 'cert', 5 => 'hybrid' ); 28 | my $needs_cert = 0; 29 | my $no_decrypt = 0; 30 | if (system("cisco-decrypt", "q") == -1) { 31 | $no_decrypt = 1; 32 | print STDERR "cisco-decrypt not in search path,\n"; 33 | print STDERR " adding passwords in obfuscated form\n"; 34 | } 35 | 36 | sub readPCF($) { 37 | my ($file) = @_; 38 | my %config; 39 | while (<$file>) { 40 | # Filter unnecessary chars at beginning & end of line 41 | s/^!*//; s/[\r ]*$//; 42 | if (/^(.*?)=(.*?)$/) { 43 | # We don't need emtpy config strings 44 | next if ($2 eq ""); 45 | if ($1 eq "Host") { 46 | $config{IPSec}{gateway} = $2; 47 | } elsif ($1 eq "GroupName") { 48 | $config{IPSec}{ID} = $2; 49 | } elsif ($1 eq "GroupPwd") { 50 | $config{IPSec}{secret} = $2; 51 | } elsif ($1 eq "enc_GroupPwd") { 52 | if ($no_decrypt) { 53 | $config{IPSec}{obfuscated} = "secret $2"; 54 | } else { 55 | $config{IPSec}{secret} = `cisco-decrypt $2`; 56 | } 57 | } elsif ($1 eq "AuthType") { 58 | $config{IKE}{Authmode} = $authmode{$2}; 59 | if ($2 == 3 || $2 == 5) { 60 | $needs_cert = 1; 61 | } 62 | } elsif ($1 eq "DHGroup") { 63 | $config{IKE}{DH} = "Group dh$2"; 64 | } elsif ($1 eq "Username") { 65 | $config{Xauth}{username} = $2; 66 | } elsif ($1 eq "UserPassword") { 67 | $config{Xauth}{password} = $2; 68 | } elsif ($1 eq "enc_UserPassword") { 69 | if ($no_decrypt) { 70 | $config{Xauth}{obfuscated} = "password $2"; 71 | } else { 72 | $config{Xauth}{password} = `cisco-decrypt $2`; 73 | } 74 | } elsif ($1 eq "NTDomain") { 75 | $config{Domain}{""} = $2; 76 | } 77 | } 78 | } 79 | return \%config; 80 | } 81 | 82 | sub writeVPNC($) { 83 | my ($config) = @_; 84 | my $text = "## generated by pcf2vpnc\n"; 85 | foreach my $section (keys %$config) { 86 | foreach my $item (keys %{ $config->{$section} }) { 87 | $text .= "$section ".($item ? "$item " : '').$config->{$section}{$item}."\n"; 88 | } 89 | } 90 | unless (defined $config->{Xauth}) { 91 | $text .= "\n## To add your username and password,\n"; 92 | $text .= "## use the following lines:\n"; 93 | $text .= "# Xauth username \n"; 94 | $text .= "# Xauth password \n"; 95 | } 96 | return $text; 97 | } 98 | 99 | if (defined $ARGV[0]) { 100 | my $src = new IO::File($ARGV[0]) || die "Unable to open file ".$ARGV[0]."\n"; 101 | if (defined $ARGV[1]) { 102 | my $dst = new IO::File($ARGV[1], "w") || die "Unable to open file ".$ARGV[1]."\n"; 103 | $dst->write( writeVPNC(readPCF($src)) ) || die "Unable to write to file ".$ARGV[1]."\n"; 104 | $dst->close() || die "Unable to close file ".$ARGV[1]."\n"; 105 | printf STDERR "vpnc config written to '%s' with permissions '%04o'.\n", $ARGV[1], (stat($ARGV[1]))[2]; 106 | print STDERR "Please take care of permissions.\n"; 107 | } else { 108 | print writeVPNC(readPCF($src)); 109 | } 110 | $src->close() || die "Unable to close file ".$ARGV[0]."\n"; 111 | if ($needs_cert) { 112 | print STDERR "\nDon't forget to copy the needed certificate(s).\n\n"; 113 | } 114 | } else { 115 | print STDERR "$0 converts VPN-config files from pcf to vpnc-format.\n"; 116 | print STDERR "Usage: $0 [vpnc file]\n"; 117 | } 118 | -------------------------------------------------------------------------------- /makeman.pl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env perl 2 | 3 | # $Id$ 4 | 5 | # Written by Wolfram Sang (wolfram@the-dreams.de) in 2007, 6 | # some inspiration from help2man by Brendan O'Dea and from Perl::Critic 7 | 8 | # Generate the vpnc-manpage from a template and the --long-help-output. 9 | # Version 0.2 10 | 11 | # Command-line options: none 12 | # Files needed : ./vpnc ./vpnc.8.template ./VERSION 13 | # Files created : ./vpnc.8 14 | # Exit status : errno-values or 255 (Magic string not found) 15 | 16 | # Distributed under the same licence as vpnc. 17 | 18 | use strict; 19 | use warnings; 20 | use Fatal qw(open close); 21 | use filetest qw(access); # to always get errno-values on filetests 22 | use POSIX qw(strftime setlocale LC_ALL); 23 | 24 | my $vpnc = './vpnc'; 25 | -e $vpnc or die "$0: Can't find $vpnc. Did you compile it?\n"; 26 | -x $vpnc or die "$0: Can't execute $vpnc. Please check permissions.\n"; 27 | 28 | # The code converting the help-output to manpage format is lots of 29 | # regex-fiddling, sorry. It got a bit more complicated by additionally 30 | # indenting lists (those originally starting with an asterisk). I hope 31 | # this pays off when converting the manpage to HTML or such. 32 | 33 | open my $LONGHELP, '-|', "$vpnc --long-help"; 34 | my $vpnc_options = ''; 35 | my $relative_indent = 0; 36 | my $indent_needed = 0; 37 | 38 | while (<$LONGHELP>) { 39 | if (/^ /) { 40 | 41 | # Check if additional indent needs to be finished by comparing the 42 | # amount of spaces at the beginning. A bit ugly, but I don't see a 43 | # better way to do it. 44 | if ($relative_indent) { 45 | /^( *)/; 46 | if (length($1) < $relative_indent) { 47 | $vpnc_options .= ".RE\n"; 48 | $relative_indent = 0; 49 | $indent_needed = 1; 50 | } 51 | } 52 | 53 | # Highlight the option and make an optional argument italic. 54 | if (s/^ *(--[\w-]+)/\n.TP\n.BI "$1"/) { 55 | s/(<.+>)/ " $1"/; 56 | } 57 | 58 | # Highlight conffile-only options. 59 | s/^ *(\(configfile only option\))/\n.TP\n.B $1/; 60 | 61 | # Position the Default-string 62 | s/^ *(Default:)/.IP\n$1/; 63 | 64 | # Highlight the conf-variable and make an optional argument italic. 65 | if (s/^ *(conf-variable:) (.+?) ?([<\n])/.P\n$1\n.BI "$2"$3/) { 66 | s/(<.+>)/ " $1"/; 67 | } 68 | 69 | # Replace asterisk with bulletin; indent if needed. 70 | if (s/^( +)\* /.IP \\(bu\n/) { 71 | if (not $relative_indent) { 72 | $vpnc_options .= ".RS\n"; 73 | $relative_indent = length $1; 74 | } 75 | } 76 | 77 | # Do we need to add an .IP-command after .RE or is there already one? 78 | if ($indent_needed and not /^\n?\.[TI]?P/) { 79 | $vpnc_options .= ".IP\n"; 80 | $indent_needed = 0; 81 | } 82 | 83 | # Finalize string and add it to buffer 84 | s/^ *//; 85 | s/ *$//; 86 | s/-/\\-/g; 87 | $vpnc_options .= $_; 88 | } 89 | } 90 | close $LONGHELP; 91 | 92 | # Hopefully the code speaks for itself from now on... 93 | 94 | setlocale( LC_ALL, 'C' ); 95 | my $write_secs = (stat("./vpnc.8.template"))[9]; 96 | my $date = strftime( '%B %Y', localtime($write_secs) ); 97 | 98 | open my $VERSION, '<', './VERSION'; 99 | my $vpnc_version = <$VERSION>; 100 | close $VERSION; 101 | chomp $vpnc_version; 102 | 103 | open my $TEMPLATE, '<', './vpnc.8.template'; 104 | open my $MANPAGE , '>', './vpnc.8'; 105 | my $magic_found; 106 | my $MAGIC_FOR_HEADER = qq(.\\" ###makeman.pl: Replace header here!\n); 107 | my $MAGIC_FOR_OPTIONS = qq(.\\" ###makeman.pl: Insert options from help-output here!\n); 108 | 109 | # Skip the template-header 110 | while (<$TEMPLATE>) { 111 | last if ($magic_found = ($_ eq $MAGIC_FOR_HEADER)); 112 | } 113 | die "$0: Missing magic: $MAGIC_FOR_HEADER" if not $magic_found; 114 | 115 | print {$MANPAGE} <<"END_MANPAGE_HEADER"; 116 | .\\" This manpage is generated! 117 | .\\" Please edit the template-file in the source-distribution only. 118 | .TH VPNC "8" "$date" "vpnc version $vpnc_version" "System Administration Utilities" 119 | END_MANPAGE_HEADER 120 | 121 | $magic_found = 0; 122 | 123 | while (<$TEMPLATE>) { 124 | if ($_ ne $MAGIC_FOR_OPTIONS) { 125 | print {$MANPAGE} $_; 126 | } else { 127 | print {$MANPAGE} $vpnc_options; 128 | $magic_found = 1; 129 | } 130 | } 131 | die "$0: Missing magic: $MAGIC_FOR_OPTIONS" if not $magic_found; 132 | 133 | close $TEMPLATE; 134 | close $MANPAGE; 135 | -------------------------------------------------------------------------------- /supp.c: -------------------------------------------------------------------------------- 1 | /* Algorithm support checks 2 | Copyright (C) 2005 Maurice Massar 3 | Reorganised 2006 by Dan Villiom Podlaski Christiansen 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | 19 | $Id$ 20 | */ 21 | 22 | #include "supp.h" 23 | #include "math_group.h" 24 | #include "config.h" 25 | #include "isakmp.h" 26 | 27 | #include 28 | #include 29 | 30 | const supported_algo_t supp_dh_group[] = { 31 | {"nopfs", 0, 0, 0, 0}, 32 | {"dh1", OAKLEY_GRP_1, IKE_GROUP_MODP_768, IKE_GROUP_MODP_768, 0}, 33 | {"dh2", OAKLEY_GRP_2, IKE_GROUP_MODP_1024, IKE_GROUP_MODP_1024, 0}, 34 | {"dh5", OAKLEY_GRP_5, IKE_GROUP_MODP_1536, IKE_GROUP_MODP_1536, 0}, 35 | /*{ "dh7", OAKLEY_GRP_7, IKE_GROUP_EC2N_163K, IKE_GROUP_EC2N_163K, 0 } note: code missing */ 36 | {NULL, 0, 0, 0, 0} 37 | }; 38 | 39 | const supported_algo_t supp_hash[] = { 40 | {"md5", GCRY_MD_MD5, IKE_HASH_MD5, IPSEC_AUTH_HMAC_MD5, 0}, 41 | {"sha1", GCRY_MD_SHA1, IKE_HASH_SHA, IPSEC_AUTH_HMAC_SHA, 0}, 42 | {NULL, 0, 0, 0, 0} 43 | }; 44 | 45 | const supported_algo_t supp_crypt[] = { 46 | {"null", GCRY_CIPHER_NONE, IKE_ENC_NO_CBC, ISAKMP_IPSEC_ESP_NULL, 0}, 47 | {"des", GCRY_CIPHER_DES, IKE_ENC_DES_CBC, ISAKMP_IPSEC_ESP_DES, 0}, 48 | {"3des", GCRY_CIPHER_3DES, IKE_ENC_3DES_CBC, ISAKMP_IPSEC_ESP_3DES, 0}, 49 | {"aes128", GCRY_CIPHER_AES128, IKE_ENC_AES_CBC, ISAKMP_IPSEC_ESP_AES, 128}, 50 | {"aes192", GCRY_CIPHER_AES192, IKE_ENC_AES_CBC, ISAKMP_IPSEC_ESP_AES, 192}, 51 | {"aes256", GCRY_CIPHER_AES256, IKE_ENC_AES_CBC, ISAKMP_IPSEC_ESP_AES, 256}, 52 | {NULL, 0, 0, 0, 0} 53 | }; 54 | 55 | const supported_algo_t supp_auth[] = { 56 | {"psk", 0, IKE_AUTH_PRESHARED, 0, 0}, 57 | {"psk+xauth", 0, IKE_AUTH_XAUTHInitPreShared, 0, 0}, 58 | #if 0 59 | {"cert(dsa)", 0, IKE_AUTH_RSA_SIG, 0, 0}, 60 | {"cert(rsasig)", 0, IKE_AUTH_DSS, 0, 0}, 61 | {"hybrid(dsa)", 0, IKE_AUTH_DSS, 0, 0}, 62 | #endif /* 0 */ 63 | {"hybrid(rsa)", 0, IKE_AUTH_HybridInitRSA, 0, 0}, 64 | {NULL, 0, 0, 0, 0} 65 | }; 66 | 67 | const supported_algo_t *get_algo(enum algo_group what, enum supp_algo_key key, int id, 68 | const char *name, int keylen) 69 | { 70 | const supported_algo_t *sa = NULL; 71 | int i = 0, val = 0; 72 | const char *valname = NULL; 73 | 74 | switch (what) { 75 | case SUPP_ALGO_DH_GROUP: 76 | sa = supp_dh_group; 77 | break; 78 | case SUPP_ALGO_HASH: 79 | sa = supp_hash; 80 | break; 81 | case SUPP_ALGO_CRYPT: 82 | sa = supp_crypt; 83 | break; 84 | case SUPP_ALGO_AUTH: 85 | sa = supp_auth; 86 | break; 87 | default: 88 | abort(); 89 | } 90 | 91 | for (i = 0; sa[i].name != NULL; i++) { 92 | switch (key) { 93 | case SUPP_ALGO_NAME: 94 | valname = sa[i].name; 95 | break; 96 | case SUPP_ALGO_MY_ID: 97 | val = sa[i].my_id; 98 | break; 99 | case SUPP_ALGO_IKE_SA: 100 | val = sa[i].ike_sa_id; 101 | break; 102 | case SUPP_ALGO_IPSEC_SA: 103 | val = sa[i].ipsec_sa_id; 104 | break; 105 | default: 106 | abort(); 107 | } 108 | if ((key == SUPP_ALGO_NAME) ? !strcasecmp(name, valname) : (val == id)) 109 | if (keylen == sa[i].keylen) 110 | return sa + i; 111 | } 112 | 113 | return NULL; 114 | } 115 | 116 | const supported_algo_t *get_dh_group_ike(void) 117 | { 118 | return get_algo(SUPP_ALGO_DH_GROUP, SUPP_ALGO_NAME, 0, config[CONFIG_IKE_DH], 0); 119 | } 120 | const supported_algo_t *get_dh_group_ipsec(int server_setting) 121 | { 122 | const char *pfs_setting = config[CONFIG_IPSEC_PFS]; 123 | 124 | if (!strcmp(config[CONFIG_IPSEC_PFS], "server")) { 125 | /* treat server_setting == -1 (unknown) as 0 */ 126 | pfs_setting = (server_setting == 1) ? "dh2" : "nopfs"; 127 | } 128 | 129 | return get_algo(SUPP_ALGO_DH_GROUP, SUPP_ALGO_NAME, 0, pfs_setting, 0); 130 | } 131 | -------------------------------------------------------------------------------- /isakmp-pkt.h: -------------------------------------------------------------------------------- 1 | /* ISAKMP packing and unpacking routines. 2 | Copyright (C) 2002 Geoffrey Keating 3 | Copyright (C) 2003-2005 Maurice Massar 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | 19 | $Id$ 20 | */ 21 | 22 | #ifndef __ISAKMP_PKT_H__ 23 | #define __ISAKMP_PKT_H__ 24 | #if defined(__linux__) 25 | #include 26 | #endif 27 | #include 28 | 29 | #include "isakmp.h" 30 | 31 | struct isakmp_attribute { 32 | struct isakmp_attribute *next; 33 | uint16_t type; 34 | enum { 35 | isakmp_attr_lots, 36 | isakmp_attr_16, 37 | isakmp_attr_2x8, 38 | isakmp_attr_acl 39 | } af; 40 | union { 41 | uint16_t attr_16; 42 | uint8_t attr_2x8[2]; 43 | struct { 44 | uint16_t length; 45 | uint8_t *data; 46 | } lots; 47 | struct { 48 | uint16_t count; 49 | struct acl_ent_s { 50 | struct in_addr addr, mask; 51 | uint16_t protocol, sport, dport; 52 | } *acl_ent; 53 | } acl; 54 | } u; 55 | }; 56 | 57 | struct isakmp_payload { 58 | struct isakmp_payload *next; 59 | enum isakmp_payload_enum type; 60 | union { 61 | struct { 62 | uint32_t doi; 63 | uint32_t situation; 64 | struct isakmp_payload *proposals; 65 | } sa; 66 | struct { 67 | uint8_t number; 68 | uint8_t prot_id; 69 | uint8_t spi_size; 70 | uint8_t *spi; 71 | struct isakmp_payload *transforms; 72 | } p; 73 | struct { 74 | uint8_t number; 75 | uint8_t id; 76 | struct isakmp_attribute *attributes; 77 | } t; 78 | struct { 79 | uint16_t length; 80 | uint8_t *data; 81 | } ke, hash, sig, nonce, vid, natd; 82 | struct { 83 | uint8_t type; 84 | uint8_t protocol; 85 | uint16_t port; 86 | uint16_t length; 87 | uint8_t *data; 88 | } id; 89 | struct { 90 | uint8_t encoding; 91 | uint16_t length; 92 | uint8_t *data; 93 | } cert, cr; 94 | struct { 95 | uint32_t doi; 96 | uint8_t protocol; 97 | uint8_t spi_length; 98 | uint8_t *spi; 99 | uint16_t type; 100 | uint16_t data_length; 101 | uint8_t *data; 102 | struct isakmp_attribute *attributes; /* sometimes, data is an attributes array */ 103 | } n; 104 | struct { 105 | uint32_t doi; 106 | uint8_t protocol; 107 | uint8_t spi_length; 108 | uint16_t num_spi; 109 | uint8_t **spi; 110 | } d; 111 | struct { 112 | uint8_t type; 113 | uint16_t id; 114 | struct isakmp_attribute *attributes; 115 | } modecfg; 116 | } u; 117 | }; 118 | 119 | struct isakmp_packet { 120 | uint8_t i_cookie[ISAKMP_COOKIE_LENGTH]; 121 | uint8_t r_cookie[ISAKMP_COOKIE_LENGTH]; 122 | uint8_t isakmp_version; 123 | uint8_t exchange_type; 124 | uint8_t flags; 125 | uint32_t message_id; 126 | struct isakmp_payload *payload; 127 | }; 128 | 129 | extern void *xallocc(size_t x); 130 | extern struct isakmp_packet *new_isakmp_packet(void); 131 | extern struct isakmp_payload *new_isakmp_payload(uint8_t); 132 | extern struct isakmp_payload *new_isakmp_data_payload(uint8_t type, const void *data, 133 | size_t data_length); 134 | extern struct isakmp_attribute *new_isakmp_attribute(uint16_t, struct isakmp_attribute *); 135 | extern struct isakmp_attribute *new_isakmp_attribute_16(uint16_t type, uint16_t data, 136 | struct isakmp_attribute *next); 137 | extern void free_isakmp_packet(struct isakmp_packet *p); 138 | extern void flatten_isakmp_payloads(struct isakmp_payload *p, uint8_t ** result, size_t * size); 139 | extern void flatten_isakmp_payload(struct isakmp_payload *p, uint8_t ** result, size_t * size); 140 | extern void flatten_isakmp_packet(struct isakmp_packet *p, 141 | uint8_t ** result, size_t * size, size_t blksz); 142 | extern struct isakmp_packet *parse_isakmp_packet(const uint8_t * data, 143 | size_t data_len, int * reject); 144 | extern void test_pack_unpack(void); 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /test-crypto.c: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; either version 2 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "crypto.h" 28 | 29 | static unsigned char *read_binfile(const char *filename, size_t *len) 30 | { 31 | int fd, ret; 32 | struct stat s; 33 | unsigned char *b; 34 | 35 | if (filename == NULL || len ==NULL) 36 | return NULL; 37 | 38 | fd = open(filename, O_RDONLY); 39 | if (fd < 0) { 40 | fprintf(stderr, "Error opening file %s\n", filename); 41 | return NULL; 42 | } 43 | 44 | ret = fstat(fd, &s); 45 | if (ret < 0) { 46 | fprintf(stderr, "Error while stat() file %s\n", filename); 47 | close(fd); 48 | return NULL; 49 | } 50 | if (s.st_size == 0) { 51 | fprintf(stderr, "Empty file %s\n", filename); 52 | close(fd); 53 | return NULL; 54 | } 55 | 56 | b = malloc(s.st_size); 57 | if (b == NULL) { 58 | fprintf(stderr, "Error allocating memory\n"); 59 | close(fd); 60 | return NULL; 61 | } 62 | 63 | ret = read(fd, b, s.st_size); 64 | if (ret != s.st_size) { 65 | fprintf(stderr, "Error reading file %s\n", filename); 66 | free(b); 67 | close(fd); 68 | return NULL; 69 | } 70 | 71 | close(fd); 72 | *len = s.st_size; 73 | return b; 74 | } 75 | 76 | int main(int argc, char *argv[]) 77 | { 78 | crypto_ctx *cctx; 79 | crypto_error *error = NULL; 80 | int i; 81 | unsigned char *data; 82 | size_t size = 0, sig_len, dec_len; 83 | unsigned char *sig_data, *dec_data; 84 | 85 | if (argc < 6) { 86 | fprintf(stderr, "Need at least 5 arguments: \n"); 87 | return 1; 88 | } 89 | 90 | cctx = crypto_ctx_new(&error); 91 | if (!cctx) { 92 | fprintf(stderr, "Error initializing crypto: %s\n", error->msg); 93 | return error->code; 94 | } 95 | 96 | /* Load certificates */ 97 | for (i = 4; i < argc; i++) { 98 | data = crypto_read_cert(argv[i], &size, &error); 99 | if (!data) { 100 | fprintf(stderr, "Error reading cert %d: %s\n", i + 1, error->msg); 101 | return error->code; 102 | } 103 | if (crypto_push_cert(cctx, data, size, &error)) { 104 | free(data); 105 | fprintf(stderr, "Error pushing cert %d: %s\n", i + 1, error->msg); 106 | return error->code; 107 | } 108 | free(data); 109 | } 110 | 111 | /* Verify the cert chain */ 112 | if (crypto_verify_chain(cctx, argv[3], NULL, &error) != 0) { 113 | fprintf(stderr, "Error verifying chain: %s\n", error && error->msg ? error->msg : "(none)"); 114 | return error->code; 115 | } 116 | 117 | /* Decrypt something using the public key of the server certificate */ 118 | sig_data = read_binfile(argv[1], &sig_len); 119 | if (sig_data == NULL) 120 | return 1; 121 | 122 | dec_data = read_binfile(argv[2], &dec_len); 123 | if (dec_data == NULL) { 124 | free(sig_data); 125 | return 1; 126 | } 127 | 128 | size = 0; 129 | data = crypto_decrypt_signature(cctx, &sig_data[0], sig_len, &size, CRYPTO_PAD_NONE, &error); 130 | if (!data || !size) { 131 | fprintf(stderr, "Error decrypting signature: %s\n", error && error->msg ? error->msg : "(none)"); 132 | free(dec_data); 133 | free(sig_data); 134 | return error->code; 135 | } 136 | 137 | if (size != dec_len) { 138 | fprintf(stderr, "Error decrypting signature: unexpected " 139 | "decrypted size %zd (expected %zu)\n", size, dec_len); 140 | free(dec_data); 141 | free(sig_data); 142 | free(data); 143 | return 1; 144 | } 145 | 146 | if (memcmp(data, dec_data, dec_len)) { 147 | fprintf(stderr, "Error decrypting signature: decrypted data did" 148 | " not match expected decrypted data\n"); 149 | free(dec_data); 150 | free(sig_data); 151 | free(data); 152 | return 1; 153 | } 154 | free(dec_data); 155 | free(sig_data); 156 | free(data); 157 | 158 | fprintf(stdout, "Success\n"); 159 | 160 | crypto_ctx_free(cctx); 161 | return 0; 162 | } 163 | 164 | -------------------------------------------------------------------------------- /crypto.h: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; either version 2 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #ifndef __CRYPTO_H__ 19 | #define __CRYPTO_H__ 20 | 21 | #include 22 | 23 | typedef struct { 24 | int code; 25 | int err; 26 | char *msg; 27 | } crypto_error; 28 | 29 | void crypto_error_set(crypto_error **error, int code, int in_errno, const char *fmt, ...); 30 | 31 | void crypto_error_free(crypto_error *error); 32 | 33 | void crypto_error_clear(crypto_error **error); 34 | 35 | void crypto_call_error(crypto_error *err); 36 | 37 | unsigned char *crypto_read_file(const char *path, size_t *out_len, crypto_error **error); 38 | 39 | #if CRYPTO_GNUTLS 40 | #include "crypto-gnutls.h" 41 | #elif CRYPTO_OPENSSL 42 | #include "crypto-openssl.h" 43 | #else 44 | #error "no crypto library defined" 45 | #endif 46 | 47 | #define CRYPTO_PAD_NONE 0 48 | #define CRYPTO_PAD_PKCS1 1 49 | 50 | /** 51 | * crypto_push_cert: 52 | * 53 | * Allocates a crypto context with the resources necessary for the specific 54 | * crypto library being used. 55 | * 56 | * Returns: a valid crypto context, or #NULL on error 57 | **/ 58 | crypto_ctx *crypto_ctx_new(crypto_error **error); 59 | 60 | /** 61 | * crypto_ctx_free: 62 | * @ctx: a valid crypto context created with crypto_ctx_new() 63 | * 64 | * Frees resources allocated by crypo_ctx_new(). 65 | **/ 66 | void crypto_ctx_free(crypto_ctx *ctx); 67 | 68 | /** 69 | * crypto_read_cert: 70 | * @path: path to certificate file in either PEM or DER format 71 | * @out_len: length of raw certificate data 72 | * @error: return location for an error 73 | * 74 | * Loads a certificate and returns the binary ASN certificate data; 75 | * 76 | * Returns: certificate data on success, NULL on error 77 | **/ 78 | unsigned char *crypto_read_cert(const char *path, 79 | size_t *out_len, 80 | crypto_error **error); 81 | 82 | /** 83 | * crypto_push_cert: 84 | * @ctx: a valid crypto context created with crypto_ctx_new() 85 | * @data: buffer containing raw certificate data 86 | * @len: length of raw certificate data 87 | * @error: return location for an error 88 | * 89 | * Pushes the given certificate onto the context's certificate stack. 90 | * 91 | * Returns: 0 on success, 1 on error 92 | **/ 93 | int crypto_push_cert(crypto_ctx *ctx, 94 | const unsigned char *data, 95 | size_t len, 96 | crypto_error **error); 97 | 98 | /** 99 | * crypto_verify_chain: 100 | * @ctx: a valid crypto context created with crypto_ctx_new() 101 | * @ca_file: path of a CA certificate file to use for verification of the 102 | * certificate stack. File may be a PEM-encoded file containing 103 | * multiple CA certificates. @ca_file is preferred over @ca_dir 104 | * @ca_dir: directory containing CA certificates to use for verification of the 105 | * certificate stack 106 | * @error: return location for an error 107 | * 108 | * Verifies the certificate stack previously built with crypto_push_cert() using 109 | * the supplied CA certificates or certificate locations. 110 | * 111 | * Returns: 0 on success, 1 on error 112 | **/ 113 | int crypto_verify_chain(crypto_ctx *ctx, 114 | const char *ca_file, 115 | const char *ca_dir, 116 | crypto_error **error); 117 | 118 | /** 119 | * crypto_decrypt_signature: 120 | * @ctx: a valid crypto context created with crypto_ctx_new() 121 | * @sig_data: encrypted signature data 122 | * @sig_len: length of encrypted signature data 123 | * @out_len: size of decrypted signature data 124 | * @error: return location for an error 125 | * 126 | * Recovers the message digest stored in @sig_data using the public key of the 127 | * last certificate on the certificate stack 128 | * 129 | * Returns: decrypted message digest, or #NULL on error 130 | **/ 131 | unsigned char *crypto_decrypt_signature(crypto_ctx *ctx, 132 | const unsigned char *sig_data, 133 | size_t sig_len, 134 | size_t *out_hash_len, 135 | unsigned int padding, 136 | crypto_error **error); 137 | 138 | #endif /* __CRYPTO_H__ */ 139 | 140 | -------------------------------------------------------------------------------- /test/cert2.pem: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 1 (0x1) 5 | Signature Algorithm: sha1WithRSAEncryption 6 | Issuer: OU=Cert, CN=cert1.pem 7 | Validity 8 | Not Before: Dec 4 13:26:13 2013 GMT 9 | Not After : Jun 2 13:26:13 2033 GMT 10 | Subject: OU=Cert, CN=cert2.pem 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | Public-Key: (2048 bit) 14 | Modulus: 15 | 00:bd:bc:80:34:96:c5:ea:6f:81:aa:91:be:f5:32: 16 | d9:8a:9f:02:67:b0:45:1c:3d:68:df:89:7d:af:be: 17 | fc:69:d4:1d:0f:72:ae:c8:4f:2c:f4:e2:04:b3:28: 18 | db:b9:05:ee:d7:87:c7:87:3f:76:b9:c7:8e:57:ec: 19 | 4a:c1:e3:8b:b4:14:d4:a3:a5:13:16:b7:18:3a:97: 20 | 5c:cd:c6:d6:aa:54:88:29:b1:75:d2:9d:2e:29:ef: 21 | e5:5c:50:46:02:13:b2:d7:1a:2e:38:50:cc:2c:fc: 22 | 62:fa:61:61:f7:86:18:a9:c9:b9:af:c0:0e:f9:d3: 23 | 88:1b:91:27:b0:e6:e6:16:98:fd:9b:f6:c4:e2:76: 24 | d2:63:da:77:21:b0:8d:a1:c8:d9:ce:84:3c:57:af: 25 | 99:19:7b:01:8c:f1:ae:e1:7c:ac:13:a6:03:a0:ab: 26 | a2:f6:ea:7d:de:b2:43:12:e5:23:ad:df:48:2e:bc: 27 | f2:76:96:2b:a0:1c:dc:60:84:d7:de:68:9e:2f:5c: 28 | f6:df:49:4e:05:8d:07:39:27:5e:49:45:88:86:33: 29 | 16:1a:5f:b1:a2:d1:78:ff:30:36:25:b8:05:c1:8a: 30 | dc:b4:6c:b6:3e:52:39:1e:61:dc:eb:bb:da:49:1d: 31 | d1:1a:06:76:22:ab:94:07:c7:0e:58:cc:e0:c6:ff: 32 | 8c:d3 33 | Exponent: 65537 (0x10001) 34 | X509v3 extensions: 35 | X509v3 Basic Constraints: 36 | CA:TRUE 37 | Signature Algorithm: sha1WithRSAEncryption 38 | 6f:02:24:5d:60:3b:76:e8:aa:a5:37:d7:75:18:72:fd:e0:9a: 39 | ce:aa:50:5e:e6:83:93:1b:2d:c4:47:5b:d6:d4:8d:d2:ba:6f: 40 | af:a7:a8:78:6a:06:78:7e:9d:83:29:7d:9b:8a:f7:8d:7b:76: 41 | d8:0d:0b:7e:b9:bd:15:e8:16:9a:c5:4b:48:c7:26:ba:37:fe: 42 | f3:8f:dd:05:13:38:31:79:1a:f4:24:49:03:6d:f8:53:d7:01: 43 | 44:79:67:ba:6a:d4:40:7d:56:4d:c4:a5:99:aa:a9:da:84:44: 44 | e8:29:ea:bd:5e:5a:7d:c0:7d:e0:7e:0c:12:85:65:ef:cd:f8: 45 | b6:56:9e:05:97:d4:48:d7:86:96:75:e6:cc:51:60:7f:eb:ed: 46 | a4:e0:9e:c6:70:d9:ce:17:8e:41:16:7b:06:3d:c7:33:d3:d9: 47 | 08:8d:17:4e:a5:13:6a:d7:e2:ce:cc:74:ce:14:76:0e:aa:1f: 48 | 8d:f5:c8:ef:a0:34:e4:ed:f8:25:b5:8d:d2:3f:65:c4:75:97: 49 | 6a:ae:0f:02:5e:61:a1:0d:a1:7c:53:fd:10:75:4f:19:71:05: 50 | 6b:26:18:4c:95:85:7f:50:0f:a5:2d:0f:0a:07:a4:aa:ce:df: 51 | 3c:32:47:14:88:73:e1:6b:70:fb:53:23:06:bb:66:91:b8:2a: 52 | 23:9f:63:ab:40:a5:71:3d:c6:0a:d3:e5:a2:c5:c8:52:36:40: 53 | 47:3c:6b:16:0c:08:d6:77:91:c5:ed:18:87:50:8e:2f:b0:83: 54 | 31:34:12:57:41:56:e8:47:69:cb:37:ea:05:3c:29:a2:b5:a3: 55 | 9a:82:08:ef:fd:2d:86:52:7d:99:eb:23:d6:28:2c:7e:bb:0a: 56 | d0:c0:6e:73:89:09:2b:13:a5:c8:29:4c:e8:02:82:76:b6:d5: 57 | 61:07:b0:78:c4:57:44:a7:c1:80:4f:51:0c:46:1e:d3:1b:45: 58 | 35:1f:34:f3:e5:4f:88:2e:cd:ee:ac:98:70:35:62:4b:ca:b1: 59 | db:37:a6:bb:24:b6:2c:71:d1:29:06:8f:7b:4b:e6:bf:86:57: 60 | 23:1a:ce:9a:c5:25:b1:fe:fc:95:4f:5b:f0:9a:32:25:07:b3: 61 | 25:87:55:e9:ed:e4:d3:76:53:f3:73:62:c7:63:ad:58:c3:8f: 62 | ee:8e:5e:4f:4a:3f:d2:a9:aa:62:a7:37:01:a8:22:de:54:e9: 63 | 06:10:7a:65:a9:06:78:47:c0:52:b4:c5:a1:a1:c1:2f:0c:f9: 64 | 14:88:31:65:fc:9f:5e:b2:09:8a:35:db:a6:4d:7b:34:e2:46: 65 | 97:b3:93:11:d6:a3:53:49:50:b0:5e:2a:64:a7:18:a0:0f:b1: 66 | 14:78:dd:35:61:89:73:2d 67 | -----BEGIN CERTIFICATE----- 68 | MIID0TCCAbmgAwIBAgIBATANBgkqhkiG9w0BAQUFADAjMQ0wCwYDVQQLDARDZXJ0 69 | MRIwEAYDVQQDDAljZXJ0MS5wZW0wHhcNMTMxMjA0MTMyNjEzWhcNMzMwNjAyMTMy 70 | NjEzWjAjMQ0wCwYDVQQLDARDZXJ0MRIwEAYDVQQDDAljZXJ0Mi5wZW0wggEiMA0G 71 | CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9vIA0lsXqb4Gqkb71MtmKnwJnsEUc 72 | PWjfiX2vvvxp1B0Pcq7ITyz04gSzKNu5Be7Xh8eHP3a5x45X7ErB44u0FNSjpRMW 73 | txg6l1zNxtaqVIgpsXXSnS4p7+VcUEYCE7LXGi44UMws/GL6YWH3hhipybmvwA75 74 | 04gbkSew5uYWmP2b9sTidtJj2nchsI2hyNnOhDxXr5kZewGM8a7hfKwTpgOgq6L2 75 | 6n3eskMS5SOt30guvPJ2liugHNxghNfeaJ4vXPbfSU4FjQc5J15JRYiGMxYaX7Gi 76 | 0Xj/MDYluAXBity0bLY+UjkeYdzru9pJHdEaBnYiq5QHxw5YzODG/4zTAgMBAAGj 77 | EDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggIBAG8CJF1gO3boqqU3 78 | 13UYcv3gms6qUF7mg5MbLcRHW9bUjdK6b6+nqHhqBnh+nYMpfZuK9417dtgNC365 79 | vRXoFprFS0jHJro3/vOP3QUTODF5GvQkSQNt+FPXAUR5Z7pq1EB9Vk3EpZmqqdqE 80 | ROgp6r1eWn3AfeB+DBKFZe/N+LZWngWX1EjXhpZ15sxRYH/r7aTgnsZw2c4XjkEW 81 | ewY9xzPT2QiNF06lE2rX4s7MdM4Udg6qH431yO+gNOTt+CW1jdI/ZcR1l2quDwJe 82 | YaENoXxT/RB1TxlxBWsmGEyVhX9QD6UtDwoHpKrO3zwyRxSIc+FrcPtTIwa7ZpG4 83 | KiOfY6tApXE9xgrT5aLFyFI2QEc8axYMCNZ3kcXtGIdQji+wgzE0EldBVuhHacs3 84 | 6gU8KaK1o5qCCO/9LYZSfZnrI9YoLH67CtDAbnOJCSsTpcgpTOgCgna21WEHsHjE 85 | V0SnwYBPUQxGHtMbRTUfNPPlT4guze6smHA1YkvKsds3prsktixx0SkGj3tL5r+G 86 | VyMazprFJbH+/JVPW/CaMiUHsyWHVent5NN2U/NzYsdjrVjDj+6OXk9KP9KpqmKn 87 | NwGoIt5U6QYQemWpBnhHwFK0xaGhwS8M+RSIMWX8n16yCYo126ZNezTiRpezkxHW 88 | o1NJULBeKmSnGKAPsRR43TVhiXMt 89 | -----END CERTIFICATE----- 90 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | TODO list 2 | 3 | * On opensolaris we need to add -interface in case the route points 4 | to an interface instead of a next hop, see 5 | http://www.cwinters.com/blog/2008/02/02/getting_vpnc_to_work_on_opensolaris.html 6 | 7 | * Add native ESP support 8 | 9 | * Allow PSK without xauth. 10 | 11 | * further research into the "packet too short" messages. 12 | - see http://lists.unix-ag.uni-kl.de/pipermail/vpnc-devel/2005-February/000553.html 13 | for more information 14 | 15 | * pass IPSEC target network to script 16 | - use it to initialize the tunnel interface and routes 17 | 18 | * clean up scripts 19 | - config-support for vpnc-script 20 | - customizable handling of routing 21 | - switch to disable resolv.conf rewriting 22 | - do $something with split_dns 23 | 24 | * beautify packet dump output 25 | 26 | * large code cleanup 27 | - at least one function per packet (instead of one function per phase) 28 | - factor out a central select-loop, send / receive code, nat-t handling 29 | - maybe even add some sort of state machine 30 | - get a rid of remaining (non-const) global variables 31 | 32 | * implement phase1 rekeying (with or without xauth-reauthentication) 33 | * implement compression 34 | * try a list of gateways (backup server) 35 | * Generate the manpage command line part directly from vpnc 36 | 37 | * optionally use in-kernel-ipsec with pf-key 38 | - merge patch 39 | 40 | * add support for pcap and dump decrypted traffic 41 | 42 | * research/bugs: 43 | - usernames containing "@" unable to login 44 | - ipsec over tcp 45 | - nortel support? 46 | - segfault if > 100 routes/acls (to large packet? read size?) 47 | (probably "fixed" by increasing the size in r_packet in vpnc.c, 48 | but why did it crash?) 49 | - amd64 somehow broken? maybe gcc bugs?? 50 | - some debug prints get the endianess wrong 51 | - In case the psk in hybrid isn't correct, the server sends annother AM_2 52 | packet - to port 500 of course, even if we are using nat-t and talked on 53 | 4500 already. We currently don't handle that. 54 | 55 | * optional drop root (rekey? reconnect? vpnc-script calls?) 56 | - Don't drop privileges, ever, but allow to be run suid. 57 | - If euid != ruid, clear out env on program start. 58 | - Sanitize variables for vpnc-script (snarf code from 59 | callscript.c from dhcpclient). 60 | - If euid != ruid, disable command line options (but not the profile 61 | parameter). 62 | - If euid != ruid, treat profiles as filenames only. They must not 63 | be paths, i.e. contain PATHSEP. Read them relative to /etc/vpnc. 64 | - Make sure vpnc-disconnect only kills processes owned by same user. 65 | 66 | * implement certificate support 67 | * implement dsa certificates in hybrid mode 68 | * Adapt lifetime (when given as time) to certificate lifetime etc 69 | (rfc2401, 4.4.3) 70 | * implement main mode for phase 1 (needed to *use* certificates in 71 | many cases) 72 | 73 | * factor out crypto stuff (cipher, hmac, dh) 74 | - http://libtomcrypt.org/features.html 75 | - http://www.foldr.org/~michaelw/ patch fertig 76 | - libgcrypt (old too?) 77 | - autodetect? 78 | - openssl?? 79 | - relicense to gpl+ssl? 80 | 81 | * links to packages, howtos, etc. 82 | - kvpnc http://home.gna.org/kvpnc/ 83 | - vpnc+Zaurus http://users.ox.ac.uk/~oliver/vpnc.html 84 | - linux-mipsel (WRT54G) http://openwrt.alphacore.net/vpnc_0.3.2_mipsel.ipk 85 | - howto-de http://localhost.ruhr.de/~stefan/uni-duisburg.ai/vpnc.shtml 86 | 87 | ---- 88 | 89 | * DONE implement hybrid-auth 90 | * DONE implement DPD, RFC 3706 Dead Peer Detection 91 | * DONE --local-address 92 | * DONE implement phase2 rekeying 93 | * DONE support rsa-SecurID token which sometimes needs 2 IDs 94 | * DONE add macosx support 95 | * DONE update "check pfs setting" error message 96 | * DONE make doing xauth optional 97 | * DONE implement udp transport NAT-T 98 | * DONE fix Makefile (install, DESTDIR, CFLAGS, ...) 99 | * DONE implement udp encap via port 10.000 100 | * DONE svn-Repository 101 | * DONE XAUTH Domain: (empty) 102 | * DONE check /dev/net/tun, reject /dev/tun* on linux 103 | * DONE spawn post-connect script 104 | * DONE ask for dns/wins servers, default domain, pfs setting, netmask 105 | * DONE automatic handling of pfs 106 | * DONE send version string 107 | * DONE send lifetime in phase1 and phase2 108 | * DONE accept (== ignore) lifetime update in phase1 109 | * DONE load balancing support (fixes INVALID_EXCHANGE_TYPE in S4.5) 110 | * DONE include OpenBSD support from Nikolay Sturm 111 | * DONE memleak fix from Sebastian Biallas 112 | * DONE fix link at alioth 113 | * DONE include man-page 114 | * DONE post rfcs and drafts 115 | * DONE post link to http://www.liebchen-online.de/vpn-zaurus.html 116 | * DONE passcode == password 117 | * DONE support for new libgcrypt versions 118 | * DONE make /var/run/vpnc as needed 119 | * DONE ignore "metric10 xx" 120 | * DONE ignore attr 32136! (Cisco extension: XAUTH Vendor) 121 | * DONE FreeBSD supported 122 | * DONE NetBSD supported 123 | * DONE fix vpnc-disconnect 124 | * DONE --verbose 125 | * DONE hide user/pass from --debug output 126 | * DONE don't ignore all notifies at ipsec-sa-negotation 127 | * DONE VERSION 128 | * DONE --pid-file 129 | * DONE --non-interactive 130 | * DONE fix delete message 131 | * DONE implement ISAKMP and IPSEC SA negotiate support 132 | -------------------------------------------------------------------------------- /test/cert1.pem: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 1 (0x1) 5 | Signature Algorithm: sha1WithRSAEncryption 6 | Issuer: OU=Cert, CN=cert0.pem 7 | Validity 8 | Not Before: Dec 4 13:26:13 2013 GMT 9 | Not After : Jun 2 13:26:13 2033 GMT 10 | Subject: OU=Cert, CN=cert1.pem 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | Public-Key: (4096 bit) 14 | Modulus: 15 | 00:b7:8a:db:2e:f3:c7:6c:2c:78:7e:29:af:66:50: 16 | d4:ff:f9:c1:29:2b:96:ad:b9:5f:c0:7b:02:39:09: 17 | cc:46:5e:24:9e:e4:57:8b:43:d6:28:ae:91:2b:38: 18 | dd:c6:e1:08:cc:22:7e:dd:87:79:06:28:98:81:b0: 19 | 35:5e:75:ca:77:f6:15:34:9f:30:f9:cb:cc:fd:ae: 20 | c6:91:1c:eb:45:fa:4b:92:fc:d6:27:ad:07:ac:20: 21 | d2:6f:19:e4:c8:6b:3f:c0:17:20:c2:56:2a:6e:46: 22 | 0d:c1:a1:39:f2:9c:65:57:8d:4b:b8:a4:60:36:13: 23 | cf:68:3a:4c:cd:35:b0:77:3a:ec:e7:18:2b:da:b2: 24 | b5:95:97:ae:22:ae:23:44:99:62:10:4d:fa:1f:62: 25 | 93:93:35:7b:19:dc:51:3e:44:63:f8:95:c1:6a:62: 26 | cf:d4:d3:67:9b:82:74:f9:d8:ac:06:0e:f6:5e:3a: 27 | 76:8f:92:12:fe:ff:9d:11:8b:21:47:d6:b1:e8:53: 28 | c4:a5:12:7d:d7:21:06:96:93:34:f0:13:57:12:3b: 29 | 3c:4f:9b:7d:c0:a6:d0:cc:d2:c3:07:b9:e8:46:62: 30 | d0:8e:49:14:1d:ae:69:34:a5:21:58:da:95:d6:af: 31 | 84:5e:de:5f:e3:c3:b6:5d:0c:fd:33:f5:fe:c1:df: 32 | 69:f7:11:0d:88:63:24:ff:1a:79:cd:76:81:2a:59: 33 | f7:32:27:6f:b0:12:1b:0c:a8:ac:b8:c3:85:f6:63: 34 | 7e:bd:bd:97:86:09:b6:1b:51:54:2e:03:02:9e:ae: 35 | 44:07:2b:48:7e:34:76:fe:f8:6e:28:81:14:8b:ef: 36 | 24:d0:eb:c3:f2:1f:4c:93:24:51:cd:5f:06:af:26: 37 | 8e:08:da:aa:8b:8a:06:f5:ed:64:c2:4f:9b:f7:05: 38 | ea:be:ab:24:1b:64:f0:01:99:40:8c:11:dd:9c:28: 39 | 5d:6e:ac:b4:c0:f2:06:e9:14:ca:e0:b4:47:af:2d: 40 | 51:4e:ee:a7:26:38:ba:97:91:8d:fe:00:19:0c:ca: 41 | ac:2b:d1:57:ca:34:f4:1c:14:21:01:25:ed:9e:4c: 42 | cd:47:f8:7f:9a:88:37:50:0f:28:71:2d:e5:23:5a: 43 | 7f:08:1c:9e:05:ab:50:f6:a0:c4:63:74:d1:88:27: 44 | 8c:c5:16:5a:f5:f0:79:77:c3:69:6d:88:17:8f:79: 45 | 24:49:d3:69:79:59:c0:63:dc:a9:db:53:ea:dd:78: 46 | 8c:7a:83:31:b4:1c:c2:8c:9e:14:85:95:9f:3c:21: 47 | c2:f6:50:53:68:d9:c2:45:cf:94:91:87:94:62:3d: 48 | b1:97:ac:96:2d:f0:c1:7c:15:62:00:91:26:58:b9: 49 | 61:4e:ff 50 | Exponent: 65537 (0x10001) 51 | X509v3 extensions: 52 | X509v3 Basic Constraints: 53 | CA:TRUE 54 | Signature Algorithm: sha1WithRSAEncryption 55 | 9f:4e:99:95:c8:87:7f:87:56:4c:88:6b:9f:9d:ca:f7:2f:07: 56 | 88:5d:0e:14:a5:1a:6c:a0:4f:36:e1:76:a7:14:8c:44:51:1d: 57 | 61:35:aa:75:16:4a:94:a8:b2:05:0e:df:21:ad:53:2e:85:ca: 58 | dc:6a:8e:cf:78:77:01:e1:d5:e6:96:e0:3d:da:29:1c:3e:82: 59 | f8:9d:c1:ad:1c:dc:88:dd:b5:cf:27:db:74:3b:7b:33:04:44: 60 | b8:ae:e8:42:ae:16:67:a3:73:13:07:85:f7:0f:cf:54:a2:91: 61 | 8f:b6:51:3c:9a:42:c4:23:47:5f:de:69:93:4b:aa:80:b4:1c: 62 | 38:67:98:ab:ae:06:16:cf:55:b3:a2:4c:29:36:60:85:05:a1: 63 | 9f:e9:a5:85:6d:95:55:6b:ea:bb:bf:eb:a9:77:a6:50:5a:95: 64 | b2:7b:f1:3d:3e:a2:fe:c9:6d:f2:b7:a2:f2:cd:a2:20:92:cc: 65 | 16:fc:2e:62:e2:a2:5d:be:59:d2:cc:13:36:ca:58:4a:5a:de: 66 | e6:89:de:e8:f9:5e:1a:ca:05:c1:dd:46:4a:e8:3d:89:a4:78: 67 | 07:65:fc:ea:55:aa:b9:3b:c9:d7:a6:e0:2d:5d:0c:b1:9a:b4: 68 | 6f:95:1b:40:ae:17:f6:c6:2c:19:51:19:a7:48:68:0d:6f:e5: 69 | 5d:e9:33:24 70 | -----BEGIN CERTIFICATE----- 71 | MIID0TCCArmgAwIBAgIBATANBgkqhkiG9w0BAQUFADAjMQ0wCwYDVQQLDARDZXJ0 72 | MRIwEAYDVQQDDAljZXJ0MC5wZW0wHhcNMTMxMjA0MTMyNjEzWhcNMzMwNjAyMTMy 73 | NjEzWjAjMQ0wCwYDVQQLDARDZXJ0MRIwEAYDVQQDDAljZXJ0MS5wZW0wggIiMA0G 74 | CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC3itsu88dsLHh+Ka9mUNT/+cEpK5at 75 | uV/AewI5CcxGXiSe5FeLQ9YorpErON3G4QjMIn7dh3kGKJiBsDVedcp39hU0nzD5 76 | y8z9rsaRHOtF+kuS/NYnrQesINJvGeTIaz/AFyDCVipuRg3BoTnynGVXjUu4pGA2 77 | E89oOkzNNbB3OuznGCvasrWVl64iriNEmWIQTfofYpOTNXsZ3FE+RGP4lcFqYs/U 78 | 02ebgnT52KwGDvZeOnaPkhL+/50RiyFH1rHoU8SlEn3XIQaWkzTwE1cSOzxPm33A 79 | ptDM0sMHuehGYtCOSRQdrmk0pSFY2pXWr4Re3l/jw7ZdDP0z9f7B32n3EQ2IYyT/ 80 | GnnNdoEqWfcyJ2+wEhsMqKy4w4X2Y369vZeGCbYbUVQuAwKerkQHK0h+NHb++G4o 81 | gRSL7yTQ68PyH0yTJFHNXwavJo4I2qqLigb17WTCT5v3Beq+qyQbZPABmUCMEd2c 82 | KF1urLTA8gbpFMrgtEevLVFO7qcmOLqXkY3+ABkMyqwr0VfKNPQcFCEBJe2eTM1H 83 | +H+aiDdQDyhxLeUjWn8IHJ4Fq1D2oMRjdNGIJ4zFFlr18Hl3w2ltiBePeSRJ02l5 84 | WcBj3KnbU+rdeIx6gzG0HMKMnhSFlZ88IcL2UFNo2cJFz5SRh5RiPbGXrJYt8MF8 85 | FWIAkSZYuWFO/wIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA 86 | A4IBAQCfTpmVyId/h1ZMiGufncr3LweIXQ4UpRpsoE824XanFIxEUR1hNap1FkqU 87 | qLIFDt8hrVMuhcrcao7PeHcB4dXmluA92ikcPoL4ncGtHNyI3bXPJ9t0O3szBES4 88 | ruhCrhZno3MTB4X3D89UopGPtlE8mkLEI0df3mmTS6qAtBw4Z5irrgYWz1Wzokwp 89 | NmCFBaGf6aWFbZVVa+q7v+upd6ZQWpWye/E9PqL+yW3yt6LyzaIgkswW/C5i4qJd 90 | vlnSzBM2ylhKWt7mid7o+V4aygXB3UZK6D2JpHgHZfzqVaq5O8nXpuAtXQyxmrRv 91 | lRtArhf2xiwZURmnSGgNb+Vd6TMk 92 | -----END CERTIFICATE----- 93 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for an IPSec VPN client compatible with Cisco equipment. 2 | # Copyright (C) 2002 Geoffrey Keating 3 | # Copyright (C) 2003-2004 Maurice Massar 4 | # Copyright (C) 2006-2007 Dan Villiom Podlaski Christiansen 5 | 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | # 20 | # $Id$ 21 | 22 | DESTDIR= 23 | PREFIX=/usr/local 24 | ETCDIR=/etc/vpnc 25 | BINDIR=$(PREFIX)/bin 26 | SBINDIR=$(PREFIX)/sbin 27 | MANDIR=$(PREFIX)/share/man 28 | DOCDIR=$(PREFIX)/share/doc/vpnc 29 | 30 | # The license of vpnc (Gpl >= 2) is quite likely incompatible with the 31 | # openssl license. Openssl is one possible library used to provide certificate 32 | # support for vpnc (hybrid only). 33 | # While it is OK for users to build their own binaries linking in openssl 34 | # with vpnc and even providing dynamically linked binaries it is probably 35 | # not OK to provide the binaries inside a distribution. 36 | # See http://www.gnome.org/~markmc/openssl-and-the-gpl.html for further 37 | # details. 38 | # Some distributions like Suse and Fedora seem to think otherwise. 39 | 40 | # Comment this in to obtain a binary with certificate support which is 41 | # GPL incompliant though. 42 | #OPENSSL_GPL_VIOLATION=yes 43 | 44 | CRYPTO_LDADD = $(shell pkg-config --libs gnutls) 45 | CRYPTO_CFLAGS = $(shell pkg-config --cflags gnutls) -DCRYPTO_GNUTLS 46 | CRYPTO_SRCS = crypto-gnutls.c 47 | 48 | ifeq ($(OPENSSL_GPL_VIOLATION), yes) 49 | CRYPTO_LDADD = -lcrypto 50 | CRYPTO_CFLAGS = -DOPENSSL_GPL_VIOLATION -DCRYPTO_OPENSSL 51 | CRYPTO_SRCS = crypto-openssl.c 52 | endif 53 | 54 | SRCS = sysdep.c vpnc-debug.c isakmp-pkt.c tunip.c config.c dh.c math_group.c supp.c decrypt-utils.c crypto.c $(CRYPTO_SRCS) 55 | BINS = vpnc cisco-decrypt test-crypto 56 | OBJS = $(addsuffix .o,$(basename $(SRCS))) 57 | CRYPTO_OBJS = $(addsuffix .o,$(basename $(CRYPTO_SRCS))) 58 | BINOBJS = $(addsuffix .o,$(BINS)) 59 | BINSRCS = $(addsuffix .c,$(BINS)) 60 | VERSION := $(shell sh mk-version) 61 | RELEASE_VERSION := $(shell cat VERSION) 62 | 63 | CC ?= gcc 64 | CFLAGS ?= -O3 -g 65 | CFLAGS += -W -Wall -Wmissing-declarations -Wwrite-strings 66 | CFLAGS += $(shell libgcrypt-config --cflags) $(CRYPTO_CFLAGS) 67 | CPPFLAGS += -DVERSION=\"$(VERSION)\" 68 | LDFLAGS ?= -g 69 | LIBS += $(shell libgcrypt-config --libs) $(CRYPTO_LDADD) 70 | 71 | ifeq ($(shell uname -s), SunOS) 72 | LIBS += -lnsl -lresolv -lsocket 73 | endif 74 | ifneq (,$(findstring Apple,$(shell $(CC) --version))) 75 | # enabled in FSF GCC, disabled by default in Apple GCC 76 | CFLAGS += -fstrict-aliasing -freorder-blocks -fsched-interblock 77 | endif 78 | 79 | all : $(BINS) vpnc.8 80 | 81 | vpnc : $(OBJS) vpnc.o 82 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 83 | 84 | vpnc.8 : vpnc.8.template makeman.pl vpnc 85 | ./makeman.pl 86 | 87 | cisco-decrypt : cisco-decrypt.o decrypt-utils.o 88 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 89 | 90 | test-crypto : sysdep.o test-crypto.o crypto.o $(CRYPTO_OBJS) 91 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 92 | 93 | .depend: $(SRCS) $(BINSRCS) 94 | $(CC) -MM $(SRCS) $(BINSRCS) $(CFLAGS) $(CPPFLAGS) > $@ 95 | 96 | vpnc-debug.c vpnc-debug.h : isakmp.h enum2debug.pl 97 | LC_ALL=C perl -w ./enum2debug.pl isakmp.h >vpnc-debug.c 2>vpnc-debug.h 98 | 99 | vpnc.ps : vpnc.c 100 | enscript -E -G -T 4 --word-wrap -o- $^ | psnup -2 /dev/stdin $@ 101 | 102 | ../vpnc-%.tar.gz : vpnc-$*.tar.gz 103 | 104 | etags : 105 | etags *.[ch] 106 | ctags : 107 | ctags *.[ch] 108 | 109 | vpnc-%.tar.gz : 110 | mkdir vpnc-$* 111 | LC_ALL=C svn info -R | awk -v RS='' -v FS='\n' '/Node Kind: file/ {print substr($$1,7)}' | \ 112 | tar -cf - -T - | tar -xf - -C vpnc-$*/ 113 | tar -czf ../$@ vpnc-$* 114 | rm -rf vpnc-$* 115 | 116 | test : all 117 | ./test-crypto test/sig_data.bin test/dec_data.bin test/ca_list.pem \ 118 | test/cert3.pem test/cert2.pem test/cert1.pem test/cert0.pem 119 | 120 | dist : VERSION vpnc.8 vpnc-$(RELEASE_VERSION).tar.gz 121 | 122 | clean : 123 | -rm -f $(OBJS) $(BINOBJS) $(BINS) tags 124 | 125 | distclean : clean 126 | -rm -f vpnc-debug.c vpnc-debug.h vpnc.ps vpnc.8 .depend 127 | 128 | install-common: all 129 | install -d $(DESTDIR)$(ETCDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(MANDIR)/man1 $(DESTDIR)$(MANDIR)/man8 $(DESTDIR)$(DOCDIR) 130 | if [ "`uname -s | cut -c-6`" = "CYGWIN" ]; then \ 131 | install vpnc-script-win $(DESTDIR)$(ETCDIR)/vpnc-script; \ 132 | install vpnc-script-win.js $(DESTDIR)$(ETCDIR); \ 133 | else \ 134 | install vpnc-script $(DESTDIR)$(ETCDIR); \ 135 | fi 136 | install -m600 vpnc.conf $(DESTDIR)$(ETCDIR)/default.conf 137 | install -m755 vpnc-disconnect $(DESTDIR)$(SBINDIR) 138 | install -m755 pcf2vpnc $(DESTDIR)$(BINDIR) 139 | install -m644 vpnc.8 $(DESTDIR)$(MANDIR)/man8 140 | install -m644 pcf2vpnc.1 $(DESTDIR)$(MANDIR)/man1 141 | install -m644 cisco-decrypt.1 $(DESTDIR)$(MANDIR)/man1 142 | install -m644 COPYING $(DESTDIR)$(DOCDIR) 143 | 144 | install : install-common 145 | install -m755 vpnc $(DESTDIR)$(SBINDIR) 146 | install -m755 cisco-decrypt $(DESTDIR)$(BINDIR) 147 | 148 | install-strip : install-common 149 | install -s -m755 vpnc $(DESTDIR)$(SBINDIR) 150 | install -s -m755 cisco-decrypt $(DESTDIR)$(BINDIR) 151 | 152 | uninstall : 153 | rm -f $(DESTDIR)$(SBINDIR)/vpnc \ 154 | $(DESTDIR)$(SBINDIR)/vpnc-disconnect \ 155 | $(DESTDIR)$(BINDIR)/pcf2vpnc \ 156 | $(DESTDIR)$(BINDIR)/cisco-decrypt \ 157 | $(DESTDIR)$(MANDIR)/man1/cisco-decrypt.1 \ 158 | $(DESTDIR)$(MANDIR)/man1/pcf2vpnc \ 159 | $(DESTDIR)$(MANDIR)/man8/vpnc.8 160 | @echo NOTE: remove $(DESTDIR)$(ETCDIR) manually 161 | 162 | .PHONY : clean distclean dist all install install-strip uninstall 163 | 164 | # 165 | -include .depend 166 | -------------------------------------------------------------------------------- /sysdep.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYSDEP_H__ 2 | #define __SYSDEP_H__ 3 | 4 | /* 5 | * Different systems define different macros. 6 | * For vpnc, this list should be used as 7 | * reference: 8 | * 9 | * __linux__ 10 | * __NetBSD__ 11 | * __OpenBSD__ 12 | * __FreeBSD__ 13 | * __DragonFly__ 14 | * __APPLE__ Darwin / MacOS X 15 | * __sun__ SunOS / Solaris 16 | * __CYGWIN__ 17 | * __SKYOS__ 18 | * 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #if !defined(__CYGWIN__) 26 | #include 27 | #include 28 | #include 29 | #endif 30 | 31 | #include "config.h" 32 | 33 | int tun_open(char *dev, enum if_mode_enum mode); 34 | int tun_close(int fd, char *dev); 35 | int tun_write(int fd, unsigned char *buf, int len); 36 | int tun_read(int fd, unsigned char *buf, int len); 37 | int tun_get_hwaddr(int fd, char *dev, uint8_t *hwaddr); 38 | 39 | /***************************************************************************/ 40 | #if defined(__linux__) || defined(__GLIBC__) 41 | #include 42 | 43 | #define HAVE_VASPRINTF 1 44 | #define HAVE_ASPRINTF 1 45 | #define HAVE_ERROR 1 46 | #define HAVE_UNSETENV 1 47 | #define HAVE_SETENV 1 48 | #endif 49 | 50 | /***************************************************************************/ 51 | #if defined(__NetBSD__) 52 | #define HAVE_SA_LEN 1 53 | 54 | #define HAVE_VASPRINTF 1 55 | #define HAVE_ASPRINTF 1 56 | #define HAVE_UNSETENV 1 57 | #define HAVE_SETENV 1 58 | #endif 59 | 60 | /***************************************************************************/ 61 | #if defined(__OpenBSD__) 62 | #define HAVE_SA_LEN 1 63 | #define NEED_IPLEN_FIX 1 64 | #define NEW_TUN 1 65 | 66 | #define HAVE_VASPRINTF 1 67 | #define HAVE_ASPRINTF 1 68 | #define HAVE_UNSETENV 1 69 | #define HAVE_SETENV 1 70 | #endif 71 | 72 | /***************************************************************************/ 73 | #if defined(__FreeBSD_kernel__) 74 | #define HAVE_SA_LEN 1 75 | #endif 76 | 77 | /***************************************************************************/ 78 | #if defined(__FreeBSD__) 79 | #define HAVE_SA_LEN 1 80 | 81 | #define HAVE_VASPRINTF 1 82 | #define HAVE_ASPRINTF 1 83 | #define HAVE_UNSETENV 1 84 | #define HAVE_SETENV 1 85 | #endif 86 | 87 | /***************************************************************************/ 88 | #if defined(__DragonFly__) 89 | #define HAVE_SA_LEN 1 90 | 91 | #define HAVE_VASPRINTF 1 92 | #define HAVE_ASPRINTF 1 93 | #define HAVE_UNSETENV 1 94 | #define HAVE_SETENV 1 95 | #endif 96 | 97 | /***************************************************************************/ 98 | #if defined(__APPLE__) 99 | #define HAVE_SA_LEN 1 100 | #define NEED_IPLEN_FIX 1 101 | 102 | #define HAVE_VASPRINTF 1 103 | #define HAVE_ASPRINTF 1 104 | #define HAVE_UNSETENV 1 105 | #define HAVE_SETENV 1 106 | #if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1070 107 | #endif 108 | #endif 109 | 110 | /***************************************************************************/ 111 | #if defined(__sun__) 112 | #define NEED_IPLEN_FIX 1 113 | 114 | #ifndef IPPROTO_ESP 115 | #define IPPROTO_ESP 50 116 | #endif 117 | 118 | /* where is this defined? */ 119 | #include 120 | const char *inet_ntop(int af, const void *src, char *dst, size_t cnt); 121 | #endif 122 | /***************************************************************************/ 123 | #if defined (__SKYOS__) 124 | #define HAVE_UNSETENV 1 125 | 126 | #ifndef IPPROTO_ENCAP 127 | #define IPPROTO_ENCAP 4 128 | #endif 129 | 130 | #ifndef IPPROTO_ESP 131 | #define IPPROTO_ESP 50 132 | #endif 133 | #endif 134 | /***************************************************************************/ 135 | #if defined (__CYGWIN__) 136 | #define HAVE_VASPRINTF 1 137 | #define HAVE_ASPRINTF 1 138 | #define HAVE_UNSETENV 1 139 | #define HAVE_SETENV 1 140 | 141 | #ifndef IPPROTO_ESP 142 | #define IPPROTO_ESP 50 143 | #endif 144 | 145 | #ifndef IPPROTO_ENCAP 146 | #define IPPROTO_ENCAP 4 147 | #endif 148 | 149 | #ifdef IFNAMSIZ 150 | #undef IFNAMSIZ 151 | #endif 152 | #define IFNAMSIZ 256 153 | 154 | /* 155 | * At the moment the Cygwin environment does not have header files 156 | * for raw ethernet access, hence we need to define here what 157 | * is usually found in net/ethernet.h and netinet/if_ether.h 158 | */ 159 | 160 | #define ETH_ALEN 6 161 | 162 | /* Ethernet header */ 163 | struct ether_header 164 | { 165 | unsigned char ether_dhost[ETH_ALEN]; /* destination eth addr */ 166 | unsigned char ether_shost[ETH_ALEN]; /* source ether addr */ 167 | unsigned short ether_type; /* packet type ID field */ 168 | } __attribute__ ((__packed__)); 169 | 170 | #define ETHERTYPE_IP 0x0800 /* IP */ 171 | #define ETHERTYPE_ARP 0x0806 /* ARP */ 172 | 173 | /* Common ARP header */ 174 | struct arphdr { 175 | unsigned short ar_hrd; /* format of hardware address */ 176 | unsigned short ar_pro; /* format of protocol address */ 177 | unsigned char ar_hln; /* length of hardware address */ 178 | unsigned char ar_pln; /* length of protocol address */ 179 | unsigned short ar_op; /* ARP opcode (command) */ 180 | }; 181 | 182 | /* Ethernet ARP header */ 183 | struct ether_arp { 184 | struct arphdr ea_hdr; /* fixed-size header */ 185 | unsigned char arp_sha[ETH_ALEN]; /* sender hardware address */ 186 | unsigned char arp_spa[4]; /* sender protocol address */ 187 | unsigned char arp_tha[ETH_ALEN]; /* target hardware address */ 188 | unsigned char arp_tpa[4]; /* target protocol address */ 189 | }; 190 | #define arp_hrd ea_hdr.ar_hrd 191 | #define arp_pro ea_hdr.ar_pro 192 | #define arp_hln ea_hdr.ar_hln 193 | #define arp_pln ea_hdr.ar_pln 194 | #define arp_op ea_hdr.ar_op 195 | 196 | #define ARPHRD_ETHER 1 /* Ethernet */ 197 | 198 | #define ARPOP_REQUEST 1 /* ARP request */ 199 | #define ARPOP_REPLY 2 /* ARP reply */ 200 | 201 | #endif 202 | /***************************************************************************/ 203 | 204 | 205 | #ifndef IPDEFTTL 206 | #define IPDEFTTL 64 /* default ttl, from RFC 1340 */ 207 | #endif 208 | 209 | #ifndef IPPROTO_IPIP 210 | #define IPPROTO_IPIP IPPROTO_ENCAP 211 | #endif 212 | 213 | #ifndef ETH_HLEN 214 | #define ETH_HLEN (sizeof(struct ether_header)) 215 | #endif 216 | 217 | #ifndef ETH_ALEN 218 | #define ETH_ALEN (sizeof(struct ether_addr)) 219 | #endif 220 | 221 | #ifndef HAVE_ERROR 222 | extern void error(int fd, int errorno, const char *fmt, ...); 223 | #endif 224 | #ifndef HAVE_VASPRINTF 225 | #include 226 | extern int vasprintf(char **strp, const char *fmt, va_list ap); 227 | #endif 228 | #ifndef HAVE_ASPRINTF 229 | extern int asprintf(char **strp, const char *fmt, ...); 230 | #endif 231 | #ifndef HAVE_SETENV 232 | extern int setenv(const char *name, const char *value, int overwrite); 233 | #endif 234 | #ifndef HAVE_UNSETENV 235 | extern int unsetenv(const char *name); 236 | #endif 237 | 238 | 239 | #endif 240 | -------------------------------------------------------------------------------- /vpnc.8.template: -------------------------------------------------------------------------------- 1 | .\" Template to generate the vpnc-manpage 2 | .\" $Id$ 3 | .\" 4 | .TH VPNC "8" "Warning: Just a template!" "vpnc man-template" "Warning: Just a template!" 5 | .\" Fake header just to make this file viewable with man. 6 | .\" ###makeman.pl: Replace header here! 7 | .SH NAME 8 | vpnc \- client for Cisco VPN3000 Concentrator, IOS and PIX 9 | .SH SYNOPSIS 10 | .B vpnc 11 | [\fI--version\fR] [\fI--print-config\fR] [\fI--help\fR] [\fI--long-help\fR] [\fIoptions\fR] [\fIconfig files\fR] 12 | .SH "DESCRIPTION" 13 | .PP 14 | This manual page documents briefly the 15 | \fBvpnc\fR and 16 | \fBvpnc\-disconnect\fR commands. 17 | .PP 18 | \fBvpnc\fR is a 19 | VPN client for the Cisco 3000 VPN Concentrator, creating a IPSec-like 20 | connection as a tunneling network device for the local system. It uses 21 | the TUN/TAP driver in Linux kernel 2.4 and above and device tun(4) 22 | on BSD. The created connection is presented as a tunneling network 23 | device to the local system. 24 | .PP 25 | OBLIGATORY WARNING: the most used configuration (XAUTH authentication 26 | with pre-shared keys and password authentication) is insecure by design, 27 | be aware of this fact when you use vpnc to exchange sensitive data like 28 | passwords! 29 | .PP 30 | The vpnc daemon by itself does not set any routes, but it calls 31 | \fBvpnc\-script\fR to do this job. \fBvpnc\-script\fR displays 32 | a connect banner. If the concentrator supplies a network list 33 | for split-tunneling these networks are added to the routing table. 34 | Otherwise the default-route will be modified to point to the tunnel. 35 | Further a host route to the concentrator is added in the later case. 36 | If the client host needs DHCP, care must be taken to add another 37 | host route to the DHCP-Server around the tunnel. 38 | .PP 39 | The \fBvpnc\-disconnect\fR command is used to terminate 40 | the connection previously created by \fBvpnc\fR 41 | and restore the previous routing configuration. 42 | 43 | .SH CONFIGURATION 44 | The daemon reads configuration data from the following places: 45 | .PD 0 46 | .IP \(bu 47 | command line options 48 | .IP \(bu 49 | config file(s) specified on the command line 50 | .IP \(bu 51 | /etc/vpnc/default.conf 52 | .IP \(bu 53 | /etc/vpnc.conf 54 | .IP \(bu 55 | prompting the user if not found above 56 | 57 | .PP 58 | 59 | vpnc can parse options and 60 | .B configuration files 61 | in any order. However the first 62 | place to set an option wins. 63 | configuration filenames 64 | which do not contain a / 65 | will be searched at 66 | .B /etc/vpnc/ 67 | and 68 | .B /etc/vpnc/.conf. 69 | Otherwise 70 | .B 71 | and 72 | .B .conf 73 | will be used. 74 | If no configuration file 75 | is specified on the command-line 76 | at all, both 77 | .B /etc/vpnc/default.conf 78 | and 79 | .B /etc/vpnc.conf 80 | will be loaded. 81 | 82 | .PP 83 | 84 | Additionally, if the configuration 85 | file "-" is specified on the command-line 86 | vpnc will read configuration from 87 | stdin. The configuration is parsed and 88 | the connection proceeds when stdin is 89 | closed or the special character CEOT 90 | (CTRL-D) is read. 91 | 92 | .SH OPTIONS 93 | The program options can be either given as arguments (but not all of them 94 | for security reasons) or be stored in a configuration file. 95 | .PD 0 96 | .\" ###makeman.pl: Insert options from help-output here! 97 | 98 | .HP 99 | \fB\-\-print\-config\fR 100 | .IP 101 | Prints your configuration; output can be used as vpnc.conf 102 | 103 | .SH FILES 104 | .I /etc/vpnc.conf 105 | .I /etc/vpnc/default.conf 106 | .RS 107 | The default configuration file. You can specify the same config 108 | directives as with command line options and additionally 109 | .B IPSec secret 110 | and 111 | .B Xauth password 112 | both supplying a cleartext password. Scrambled passwords from the Cisco 113 | configuration profiles can be used with 114 | .B IPSec obfuscated secret 115 | and 116 | .B Xauth obfuscated password. 117 | 118 | See 119 | .BR EXAMPLES 120 | for further details. 121 | .RE 122 | 123 | .I /etc/vpnc/*.conf 124 | .RS 125 | vpnc will read configuration files in this directory when 126 | the config filename (with or without .conf) is specified on the command line. 127 | .RE 128 | 129 | 130 | .SH EXAMPLES 131 | This is an example vpnc.conf with pre-shared keys: 132 | 133 | .RS 134 | .PD 0 135 | IPSec gateway vpn.example.com 136 | .P 137 | IPSec ID ExampleVpnPSK 138 | .P 139 | IKE Authmode psk 140 | .P 141 | IPSec secret PskS3cret! 142 | .P 143 | Xauth username user@example.com 144 | .P 145 | Xauth password USecr3t 146 | .PD 147 | .RE 148 | 149 | And another one with hybrid authentication (requires that vpnc was 150 | built with openssl support): 151 | 152 | .RS 153 | .PD 0 154 | IPSec gateway vpn.example.com 155 | .P 156 | IPSec ID ExampleVpnHybrid 157 | .P 158 | IKE Authmode hybrid 159 | .P 160 | 161 | .P 162 | CA-Dir /etc/vpnc 163 | .P 164 | \fBor\fR 165 | .P 166 | CA-File /etc/vpnc/vpn-example-com.pem 167 | .P 168 | 169 | .P 170 | IPSec secret HybS3cret? 171 | .P 172 | Xauth username user@example.com 173 | .P 174 | Xauth password 123456 175 | .PD 176 | .RE 177 | 178 | The lines begin with a keyword (no leading spaces!). 179 | The values start exactly one space after the keywords, and run to the end of 180 | line. This lets you put any kind of weird character (except CR, LF and NUL) in 181 | your strings, but it does mean you can't add comments after a string, or spaces 182 | before them. 183 | 184 | In case the the \fBCA-Dir\fR option is used, your certificate needs to be 185 | named something like 722d15bd.X, where X is a manually assigned number to 186 | make sure that files with colliding hashes have different names. The number 187 | can be derived from the certificate file itself: 188 | .P 189 | openssl x509 \-subject_hash \-noout \-in /etc/vpnc/vpn\-example\-com.pem 190 | 191 | See also the 192 | .B \-\-print\-config 193 | option to generate a config file, and the example file in the package 194 | documentation directory where more advanced usage is demonstrated. 195 | 196 | Advanced features like manual setting of multiple target routes and 197 | disabling /etc/resolv.conf rewriting is documented in the README of the 198 | vpnc package. 199 | 200 | 201 | .SH AUTHOR 202 | This man-page has been written by Eduard Bloch and 203 | Christian Lackas , based on vpnc README by 204 | Maurice Massar . 205 | Permission is 206 | granted to copy, distribute and/or modify this document under 207 | the terms of the GNU General Public License, Version 2 any 208 | later version published by the Free Software Foundation. 209 | .PP 210 | On Debian systems, the complete text of the GNU General Public 211 | License can be found in /usr/share/common\-licenses/GPL. 212 | .SH "SEE ALSO" 213 | .BR pcf2vpnc (1), 214 | .BR cisco\-decrypt (1), 215 | .BR ip (8), 216 | .BR ifconfig (8), 217 | .BR route (1), 218 | .BR http://www.unix\-ag.uni\-kl.de/~massar/vpnc/ 219 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | A VPN client compatible with Cisco's EasyVPN equipment. 2 | 3 | Supports IPSec (ESP) with Mode Configuration and Xauth. Supports only 4 | shared-secret IPSec authentication with Xauth, 5 | AES (256, 192, 128), 3DES, 1DES, MD5, SHA1, 6 | DH1/2/5 and IP tunneling. 7 | 8 | It runs entirely in userspace. Only "Universal TUN/TAP device 9 | driver support" is needed in kernel. 10 | 11 | Project home page: http://www.unix-ag.uni-kl.de/~massar/vpnc/ 12 | 13 | 14 | ========= Contents of this file ============================================ 15 | 16 | 17 | - General configuration of vpnc 18 | - Using a modified script 19 | - Additional steps to configure hybrid authentication 20 | - Setting up vpnc on Vista 64bit 21 | - Known problems 22 | 23 | 24 | ========= General configuration of vpnc ==================================== 25 | 26 | 27 | Required Libraries: libgcrypt (version 1.1.90 for 0.2-rm+zomb-pre7 or later) 28 | libopenssl (optional, to provide hybrid support) 29 | 30 | It reads configuration data from the following places: 31 | 32 | - From command-line options 33 | - From config file(s) specified on the command line 34 | - From /etc/vpnc/default.conf only if no configfile was given on the command line 35 | - From /etc/vpnc.conf same as default.conf, ie: both are used, or none 36 | - If a setting is not given in any of those places, it prompts the user. 37 | 38 | The configuration information it currently needs is: 39 | 40 | Option Config file item 41 | --gateway IPSec gateway 42 | --id IPSec ID 43 | (no option) IPSec secret 44 | --username Xauth username 45 | (no option) Xauth password 46 | 47 | A sample configuration file is: 48 | 49 | # This is a sample configuration file. 50 | IPSec gateway 127.0.0.1 51 | IPSec ID laughing-vpn 52 | IPSec secret hahaha 53 | Xauth username geoffk 54 | 55 | Note that all strings start exactly one space after the keyword 56 | string, and run to the end of the line. This lets you put any kind of 57 | weird character (except CR, LF and NUL) in your strings, but it does mean 58 | you can't add comments after a string, or spaces before them. 59 | 60 | It may be easier to use the --print-config option to generate the 61 | config file, and then delete any lines (like a password) that you want 62 | to be prompted for. 63 | 64 | If you don't know the Group ID and Secret string, ask your 65 | administrator. If (s)he declines and refers to the 66 | configuration files provided for the vpnclient program, tell 67 | him/her that the contents of that files is (though scrambled) 68 | not really protected. If you have a working configuration file 69 | (.pcf file) for the Cisco client then you can use the pcf2vpnc 70 | utility instead, which will extract most/all of the required 71 | information and convert it into a vpnc configuration file. 72 | 73 | 74 | ========= Using a modified script ========================================== 75 | 76 | 77 | Please note that vpnc itself does NOT setup routing. You need to do this 78 | yourself, or use --script "Script" in the config file. 79 | The default script is /etc/vpnc/vpnc-script which sets a default route 80 | to the remote network, or if the Concentrator provided split-network 81 | settings, these are used to setup routes. 82 | 83 | This option is passed to system(), so you can use any shell-specials you 84 | like. This script gets called three times: 85 | $reason == pre-init: this is before vpnc opens the tun device 86 | so you can do what is necessary to ensure that it is available. 87 | Note that none of the variables mentioned below is available 88 | $reason == connect: this is what used to be "Config Script". 89 | The connection is established, but vpnc will not begin forwarding 90 | packets until the script finishes. 91 | $reason == disconnect: This is called just after vpnc received a signal. 92 | Note that vpnc will not forward packets anymore while the script is 93 | running or thereafter. 94 | 95 | Information is passed from vpnc via environment variables: 96 | 97 | #* reason -- why this script was called, one of: pre-init connect disconnect 98 | #* VPNGATEWAY -- vpn gateway address (always present) 99 | #* TUNDEV -- tunnel device (always present) 100 | #* INTERNAL_IP4_ADDRESS -- address (always present) 101 | #* INTERNAL_IP4_NETMASK -- netmask (often unset) 102 | #* INTERNAL_IP4_DNS -- list of dns servers 103 | #* INTERNAL_IP4_NBNS -- list of wins servers 104 | #* CISCO_DEF_DOMAIN -- default domain name 105 | #* CISCO_BANNER -- banner from server 106 | #* CISCO_SPLIT_INC -- number of networks in split-network-list 107 | #* CISCO_SPLIT_INC_%d_ADDR -- network address 108 | #* CISCO_SPLIT_INC_%d_MASK -- subnet mask (for example: 255.255.255.0) 109 | #* CISCO_SPLIT_INC_%d_MASKLEN -- subnet masklen (for example: 24) 110 | #* CISCO_SPLIT_INC_%d_PROTOCOL -- protocol (often just 0) 111 | #* CISCO_SPLIT_INC_%d_SPORT -- source port (often just 0) 112 | #* CISCO_SPLIT_INC_%d_DPORT -- destination port (often just 0) 113 | 114 | Currently vpnc-script is not directly configurable from configfiles. 115 | However, a workaround is to use a "wrapper-script" like this, to 116 | disable /etc/resolv.conf rewriting and setup a custom split-routing: 117 | 118 | ------------------------------ 119 | #!/bin/sh 120 | 121 | # this effectively disables changes to /etc/resolv.conf 122 | INTERNAL_IP4_DNS= 123 | 124 | # This sets up split networking regardless 125 | # of the concentrators specifications. 126 | # You can add as many routes as you want, 127 | # but you must set the counter $CISCO_SPLIT_INC 128 | # accordingly 129 | CISCO_SPLIT_INC=1 130 | CISCO_SPLIT_INC_0_ADDR=131.246.89.7 131 | CISCO_SPLIT_INC_0_MASK=255.255.255.255 132 | CISCO_SPLIT_INC_0_MASKLEN=32 133 | CISCO_SPLIT_INC_0_PROTOCOL=0 134 | CISCO_SPLIT_INC_0_SPORT=0 135 | CISCO_SPLIT_INC_0_DPORT=0 136 | 137 | . /etc/vpnc/vpnc-script 138 | ------------------------------ 139 | 140 | Store this example script, for example in /etc/vpnc/custom-script, 141 | do a "chmod +x /etc/vpnc/custom-script" and add 142 | "Script /etc/vpnc/custom-script" to your configuration. 143 | 144 | 145 | ========= Additional steps to configure hybrid authentication ============== 146 | 147 | 148 | To use the hybrid extension add 149 | Use Hybrid Auth 150 | to your .conf file or add 151 | --hybrid 152 | when starting vpnc. 153 | 154 | The trusted root certificate may be passed by adding 155 | CA-File 156 | to your .conf file or adding 157 | --ca-file 158 | when starting vpnc. 159 | 160 | The trusted root certificate may be contained in a directory by adding 161 | CA-Dir 162 | to your .conf file or adding 163 | --ca-dir 164 | when starting vpnc. 165 | The default is 166 | /etc/ssl 167 | 168 | As the trusted certificate is referenced by the hash of the subject name, 169 | the directory has to contain the certificate named like this hash_value. 170 | A link can also be used like in /etc/ssl/certs/. 171 | The hash value can be calculated by e.g. 172 | openssl x509 -in -noout -hash 173 | 174 | 175 | ========= Setting up vpnc on Vista 64bit =================================== 176 | 177 | 178 | 1. Install cygwin onto vista. Details here: http://www.cygwin.com/ 179 | 2. Make sure you install the development options for cygwin to give you 180 | access to make and gcc etc 181 | 3. Make sure you install libgcrypt for cygwin as it is needed in the make 182 | 4. Modify the bash.exe to run as administrator or you will have 183 | privilege issues later, this is done on the properties tab of the 184 | executable in c:/cygwin/bin 185 | 4. Download the latest vpnc tarball from here 186 | http://www.unix-ag.uni-kl.de/~massar/vpnc/ 187 | 5. Unzip and explode the tarball 188 | 6. modify tap-win32.h to change #define TAP_COMPONENT_ID "tap0801" to 189 | "tap0901" (No sure if this is necessary but I did it and it is working 190 | for me) 191 | 7. make 192 | 8. You should have a shinny new vpnc.exe 193 | 9. Download openvpn from http://openvpn.net/download.html. I used 194 | openvpn-2.1_rc4-install.exe as all other version I tried had errors 195 | during install 196 | 10. Run the exe but only install the TAP-Win32 Adapter V9 197 | 11. Go to control Panel | Network Connections and rename the TAP device 198 | to my-tap 199 | 12. create a /etc/vpnc/default.conf file something like this 200 | ------------- begin ------------- 201 | IPSec gateway YOURGATEWAY 202 | IPSec ID YOURID 203 | IPSec obfuscated secret YOURREALYLONGHEXVALUE (you can use your clear 204 | text password here if you remove obfuscated) 205 | Xauth username YOURUSERNAME 206 | Xauth password YOURPASSWORD 207 | Interface name my-tap 208 | Interface mode tap 209 | Local Port 0 210 | ------------- end --------------- 211 | See the general config section above and the manpage for details. 212 | 213 | 214 | ========= Known problems =================================================== 215 | 216 | 217 | Known problems: 218 | 219 | Problem: 220 | In some environments it may happen that stuff works for a while and then 221 | stops working. 222 | 223 | Reason: 224 | The dhcp leases are very short intervals and on each renew the dhcp 225 | client overwrites things like /etc/resolv.conf and maybe the default route. 226 | 227 | Solution: 228 | Fix your dhcpclient. On Debian that problem can be fixed by installing 229 | and using resolvconf to modify that file instead of modifying it directly. 230 | 231 | 232 | ============================================================================ 233 | 234 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | * vpnc-0.5.3.tar.gz Wed Nov 19 21:29:22 CET 2008 2 | 3 | User visible changes: 4 | 5 | * Don't crash while rekeying, by Maurice Massar 6 | * Fix lifetime handling if both options are present, by Maurice Massar 7 | * Support providing the destination network's netmask 8 | * Working with concentrators that require a firewall capable 9 | client might work, by Nicholas Reilly 10 | * Fix a case where pcf2vpnc would create an incorrect config line, 11 | by Wolfram Sang 12 | * Make vpnc work with newer development versions of openvpn on 13 | Windows, by Paolo Zarpellon 14 | * print logmessages while opening tun to syslog as well as stderr 15 | 16 | * vpnc-0.5.2.tar.gz Wed Nov 19 17:49:46 CET 2008 17 | 18 | User visible changes: 19 | 20 | * Install the license file with the binary 21 | * Fix routing issues in vpcn-script-win.js, by Paolo Zarpellon 22 | * Fix Phase 2 rekeying, by various authors 23 | * Improvements to debug messages, by various authors 24 | * Support for the NEXT_PIN for SecureID, by Phil Dibowitz and Rob West 25 | * Print hints on how to fix some error conditions 26 | * Add --target-network option, by Stelian Pop and Tom Schneider 27 | * Try to work around the "payload too short" message instead 28 | of aborting, by John Williams 29 | * Fix some problems with keepalives during xauth on SonicWall and 30 | ScreenOS >= 6, by Johan Fischer 31 | * Improvements to syslog messages, by various authors 32 | * On Linux calculate the MTU size instead of hardcoding it, by 33 | Tomas Mraz 34 | * Remove pid file also when not running daemonized, by Martin von Gagern 35 | * Always send FW_TYPE xauth attribute, by Johan Dahlin 36 | * Fix default route while setting DNS on Darwin, by Felix Buenemann 37 | 38 | Under the hood: 39 | * Move decryption code into its own files, by Wolfram Sang 40 | * Use ony awk instead of awk+sed in vpnc-script, by Jukka Salmi 41 | * Fix some alignment errors on ARM, by Karzist 42 | * Memory handling fixes, by various authors 43 | 44 | * vpnc-0.5.1.tar.gz Mon Sep 10 23:16:41 CEST 2007 45 | 46 | * link against -lcrypto instead of -lssl, fix from: Christophe Thil 47 | * fixed crashes on 64bit platforms by Tomas Mraz, report by Brian Downing 48 | * fixes to keepalive code from Brian Downing 49 | * generate options part of the manpage automatically, by Wolfram Sang 50 | * fix dead peer detection problems with Sonicwall, by Gerald Hanusch 51 | and Wolfgang Astleitner 52 | * fix disconnect problems with Sonicwall (please test if it fixes the known 53 | problems with Cisco), by Gerald Hanusch and Wolfgang Astleitner 54 | * again special thanks Joerg Mayer for handling all patches since the 55 | last release (-: 56 | * various other fixes contributed by Scott Rankin, Markus Meschederu 57 | 58 | * vpnc-0.5.0.tar.gz Thu Aug 30 19:17:10 CEST 2007 59 | 60 | * Dead-Peer-Detection support by Kyle McKay 61 | * Hybrid-Auth support by Andreas Hoffmann, merged by Chris Walter 62 | (depends on OpenSSL, deactivatable at compile-time) 63 | * granted Joerg Mayer svn commit privileges, special thanks to him 64 | for doing so much work on vpnc during the last month (-: 65 | * various other fixes contributed by Petr Salinger, 66 | Christian Faulhammer, Kyle McKay, Paolo Zarpellon, Joerg Mayer, 67 | Marcus Obst, Mika Liljeberg, Eduard Bloch, Wolfram Sang, Jukka 68 | Salmi, Gustavo Sverzut Barbieri, Soren Hansen, Mike Javorski. 69 | * first round of a general code cleanup (far less global variables 70 | / etc) 71 | 72 | * vpnc-0.4.0.tar.gz Mon Feb 19 22:22:22 CET 2007 73 | 74 | * DragonFly BSD support by Hans-Werner Hilse 75 | * Solaris 10 fixes by Sunil 76 | * support to read obfuscated passwords from .pcf files, based on 77 | work from "HAL-9000@evilscientists.de" 78 | * granted Dan Villiom Podlaski Christiansen svn commit privileges 79 | * Darwin support by Dan Villiom Podlaski Christiansen 80 | * UDP IP keepalive support from FreeBSD port 81 | * Juniper/ScreenOS support from Marc Huber 82 | * replace "--disable-natt --force-natt --udp" with "--natt-mode" 83 | * null cipher support from Simon Lipp 84 | * Windows/Cygwin and tap support from Paolo Zarpellon 85 | * rekeying support 86 | * various other fixes contributed by Joerg Mayer, Heiko Stamer, 87 | Plamen Todorov, Asgeir, Jukka Salmi, Wolfram Sang, Laurence 88 | MOINDROT, Chris Osicki, Anton Altaparmakov, Adam Simpkins, Ken 89 | Bell, Hanno Boeck, Kyle McKay, Dennis Schneider 90 | 91 | * vpnc-0.3.3.tar.gz Sat May 14 12:23:27 CEST 2005 92 | 93 | * ignore \r in config files 94 | * (hopefuly) fixed 64bit bugs (Nicolas Boichat and Zach Brown) 95 | * added support for "Split-Net" Routing 96 | * introduced vpnc-script and removed vpnc-connect 97 | * always search for configfiles in /etc/vpnc/ expect if the 98 | filename contains at least one "/" 99 | * only read /etc/vpnc/default.conf and /etc/vpnc.conf if no other 100 | configfiles are provided 101 | * various other fixes contributed by Anton Altaparmakov, Randy 102 | Chou, "krabat", Andre Vanha and Nikolay Sturm 103 | 104 | * vpnc-0.3.2.tar.gz Mon Nov 22 01:14:29 CET 2004 105 | 106 | * added support for preshared without xauth 107 | * fixed NAT-T support with IOS and PIX 108 | * fixed IP-Len header (Christian Lackas) 109 | * fixed reconnection problems with IOS and PIX 110 | 111 | * vpnc-0.3.1.tar.gz Sat Nov 13 01:46:42 CET 2004 112 | 113 | * fixed segfault in --print-config 114 | 115 | * vpnc-0.3.tar.gz Sat Nov 13 01:16:37 CET 2004 116 | 117 | * included IPSec over UDP and NAT-T support, thanks to Tomas Mraz 118 | and Martin von Gagern 119 | * added support for interactive authentication (security tokens for 120 | example) 121 | * fixed IOS support 122 | * updated man-page 123 | * updated TODO list 124 | * fixed byte-order in debug ouput 125 | 126 | * vpnc-0.2-rm+zomb.1.tar.gz Thu May 13 23:34:09 CEST 2004 127 | 128 | * Fixed an off-by-two bug, thanks to Christian Lackas for this 129 | * Fixed Solaris7 supported (Solaris9 does not work probably because 130 | of built-in IPsec support) 131 | * added support for (NT-) Domain xauth attribute 132 | * cleaned up and reformatted --help output 133 | * Fixed Application Version vpnc sends, fixes problems with some 134 | vpn-concentrator default config where vpnc is incorrectly 135 | detected as hardware client.. 136 | 137 | * vpnc-0.2-rm+zomb-pre9.tar.gz Sun May 2 05:32:00 CEST 2004 138 | 139 | * Fixed PIX supported (and PIXs are broken (-;) 140 | * send and ignore lifetime update in isakmp-sa/ipsec-sa 141 | * Fixed vpnc-connect to supporte load-balancing, see below 142 | * added --script which gets all modecfg infos like dns-server. see 143 | README 144 | * automatically get pfs setting from server. --pfs should not be 145 | needed anymore (broken PIXs excluded) 146 | * single DES support can be enabled with --enable-1des 147 | 148 | * vpnc-0.2-rm+zomb-pre8.tar.gz Sun Apr 25 02:13:30 CEST 2004 149 | 150 | * Fixed OpenBSD supported 151 | * added support for "Cisco extension: Load Balancing" 152 | * ignore lifetime update in phase1 153 | 154 | * vpnc-0.2-rm+zomb-pre7.tar.gz Wed Dec 17 20:58:51 CET 2003 155 | 156 | * Fixed FreeBSD supported 157 | * ignore "Cisco extension: XAUTH Vendor" XAuth-Attribute 158 | * treat passcode as password 159 | * filter "metric10 64" and the like from ip route get output 160 | * updated to libgcrypt-1.1.90 161 | * create /var/run/vpnc/ as necessary 162 | 163 | * vpnc-0.2-rm+zomb-pre6.tar.gz Sun Nov 2 02:15:56 CET 2003 164 | 165 | * Fixed NetBSD supported (add routes like this: route add -host 166 | 131.246.89.7 -ifp tun0 131.246.89.7) 167 | * cosmetic fixes 168 | 169 | * vpnc-0.2-rm+zomb-pre5.tar.gz Thu Oct 30 00:53:02 CET 2003 170 | 171 | * created debug levels: 0 default/nothing, 1 basic, 2 control flow, 172 | 3 packet dump, 99 including username/password (hex encoded) 173 | * small fixes to connect/disconnect scripts 174 | * added --local-port to allow multiple instances of vpnc running 175 | (use 0 to get a "random" port) 176 | 177 | * vpnc-0.2-rm+zomb-pre4.tar.gz Tue Oct 28 02:34:42 CET 2003 178 | 179 | * fixed handling of errors at ipsec-sa-negotiation stage 180 | * cleaned up option handling, help, version 181 | * small fixes to connect/disconnect scripts 182 | 183 | * vpnc-0.2-rm+zomb-pre3.tar.gz Sun Oct 26 06:04:09 CET 2003 184 | 185 | * added support for dh1 dh2 dh5 (pfs or ike-sa), sha1, aes128 186 | aes192 aes256 187 | * automatic negotiation of encryption/hash method (Note: dh-group / 188 | pfs is not negotiable) 189 | * cleaned up option handling 190 | * small fixes to connect/disconnect scripts 191 | 192 | * vpnc-0.2-rm+zomb-pre2.tar.gz Fri Oct 24 20:27:56 CEST 2003 193 | 194 | * debugging and detach configurable 195 | * akward hanlding of options which don't require an argument 196 | 197 | * vpnc-0.2-rm+zomb-pre1.tar.gz Thu Oct 23 06:13:02 CEST 2003 198 | 199 | * first version with libgcrypt instead of openssl (GPL compatible). 200 | * far to much debugging enabled (-; 201 | * works with a Version 4 VPN Concentrator. 202 | * supports only 3des-md5-dh2 and no-pfs. 203 | 204 | * vpnc-0.1.tar.gz 205 | 206 | * original version from Geoffrey Keating. 207 | * doesn't work with a Version 4 VPN Concentrator. 208 | -------------------------------------------------------------------------------- /crypto-openssl.c: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; either version 2 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "config.h" 24 | #include "sysdep.h" 25 | #include "crypto.h" 26 | 27 | crypto_ctx *crypto_ctx_new(crypto_error **error) 28 | { 29 | crypto_ctx *ctx; 30 | 31 | ctx = malloc(sizeof(crypto_ctx)); 32 | if (!ctx) { 33 | crypto_error_set(error, 1, ENOMEM, 34 | "not enough memory for crypto context"); 35 | return NULL; 36 | } 37 | 38 | OpenSSL_add_all_ciphers(); 39 | OpenSSL_add_all_digests(); 40 | OpenSSL_add_all_algorithms(); 41 | ERR_load_crypto_strings(); 42 | 43 | memset(ctx, 0, sizeof(crypto_ctx)); 44 | ctx->stack = sk_X509_new_null(); 45 | if (!ctx->stack) { 46 | crypto_ctx_free(ctx); 47 | crypto_error_set(error, 1, ENOMEM, 48 | "not enough memory for crypto certificate stack"); 49 | ctx = NULL; 50 | } 51 | 52 | return ctx; 53 | } 54 | 55 | void crypto_ctx_free(crypto_ctx *ctx) 56 | { 57 | if (ctx) { 58 | if (ctx->stack) 59 | sk_X509_free(ctx->stack); 60 | 61 | memset(ctx, 0, sizeof(crypto_ctx)); 62 | free(ctx); 63 | } 64 | } 65 | 66 | static int password_cb(char *buf, int size, int rwflag, void *userdata) 67 | { 68 | /* Dummy callback to ensure openssl doesn't prompt for a password */ 69 | return 0; 70 | } 71 | 72 | unsigned char *crypto_read_cert(const char *path, 73 | size_t *out_len, 74 | crypto_error **error) 75 | { 76 | FILE *fp; 77 | X509 *cert = NULL; 78 | unsigned char *data = NULL, *p; 79 | 80 | fp = fopen(path, "r"); 81 | if (!fp) { 82 | crypto_error_set(error, 1, 0, "certificate (%s) could not be opened", path); 83 | return NULL; 84 | } 85 | 86 | cert = PEM_read_X509(fp, NULL, password_cb, NULL); 87 | fclose (fp); 88 | 89 | if (!cert) { 90 | /* Try DER then */ 91 | p = data = crypto_read_file(path, out_len, error); 92 | if (!data || !*out_len) { 93 | crypto_error_set(error, 1, 0, "could not read certificate %s", path); 94 | return NULL; 95 | } 96 | 97 | cert = d2i_X509(NULL, (const unsigned char **) &p, (int) (*out_len)); 98 | if (!cert) { 99 | free(data); 100 | crypto_error_set(error, 1, 0, "could not allocate memory for certificate"); 101 | return NULL; 102 | } 103 | 104 | return data; 105 | } 106 | 107 | /* Get length of DER data */ 108 | *out_len = i2d_X509(cert, NULL); 109 | if (!*out_len) { 110 | crypto_error_set(error, 1, 0, "invalid certificate length"); 111 | goto out; 112 | } 113 | 114 | p = data = malloc(*out_len); 115 | if (!data) { 116 | crypto_error_set(error, 1, 0, "could not allocate memory for certificate"); 117 | goto out; 118 | } 119 | 120 | /* Encode the certificate to DER */ 121 | *out_len = i2d_X509(cert, &p); 122 | if (!*out_len) { 123 | crypto_error_set(error, 1, 0, "could not export certificate data"); 124 | if (data) { 125 | free(data); 126 | data = NULL; 127 | } 128 | goto out; 129 | } 130 | 131 | out: 132 | if (cert) 133 | X509_free(cert); 134 | return data; 135 | } 136 | 137 | int crypto_push_cert(crypto_ctx *ctx, 138 | const unsigned char *data, 139 | size_t len, 140 | crypto_error **error) 141 | { 142 | X509 *cert = NULL; 143 | 144 | if (!ctx || !data || (len <= 0)) { 145 | crypto_error_set(error, 1, 0, "invalid crypto context or data"); 146 | return 1; 147 | } 148 | 149 | /* convert the certificate to an openssl-X509 structure and push it onto the chain stack */ 150 | cert = d2i_X509(NULL, &data, (int) len); 151 | if (!cert) { 152 | ERR_print_errors_fp(stderr); 153 | crypto_error_set(error, 1, 0, "failed to decode certificate"); 154 | return 1; 155 | } 156 | sk_X509_push(ctx->stack, cert); 157 | return 0; 158 | } 159 | 160 | int crypto_verify_chain(crypto_ctx *ctx, 161 | const char *ca_file, 162 | const char *ca_dir, 163 | crypto_error **error) 164 | { 165 | X509 *x509; 166 | X509_STORE *store = NULL; 167 | X509_LOOKUP *lookup = NULL; 168 | X509_STORE_CTX *verify_ctx = NULL; 169 | int ret = 1; 170 | 171 | if (!ctx) { 172 | crypto_error_set(error, 1, 0, "invalid crypto context"); 173 | return 1; 174 | } 175 | 176 | x509 = sk_X509_value(ctx->stack, sk_X509_num(ctx->stack) - 1); 177 | if (x509 == NULL) { 178 | ERR_print_errors_fp (stderr); 179 | crypto_error_set(error, 1, 0, "no certificates in the stack"); 180 | return 1; 181 | } 182 | 183 | /* BEGIN - verify certificate chain */ 184 | /* create the cert store */ 185 | if (!(store = X509_STORE_new())) { 186 | crypto_error_set(error, 1, 0, "error creating X509_STORE object"); 187 | return 1; 188 | } 189 | /* load the CA certificates */ 190 | if (X509_STORE_load_locations (store, ca_file, ca_dir) != 1) { 191 | crypto_error_set(error, 1, 0, "error loading the CA file (%s) " 192 | "or directory (%s)", ca_file, ca_dir); 193 | goto out; 194 | } 195 | if (X509_STORE_set_default_paths (store) != 1) { 196 | crypto_error_set(error, 1, 0, "error loading the system-wide CA" 197 | " certificates"); 198 | goto out; 199 | } 200 | 201 | #if 0 202 | /* check CRLs */ 203 | /* add the corresponding CRL for each CA in the chain to the lookup */ 204 | #define CRL_FILE "root-ca-crl.crl.pem" 205 | 206 | if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()))) { 207 | crypto_error_set(error, 1, 0, "error creating X509 lookup object."); 208 | goto out; 209 | } 210 | if (X509_load_crl_file(lookup, CRL_FILE, X509_FILETYPE_PEM) != 1) { 211 | ERR_print_errors_fp(stderr); 212 | crypto_error_set(error, 1, 0, "error reading CRL file"); 213 | goto out; 214 | } 215 | X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); 216 | #endif /* 0 */ 217 | 218 | /* create a verification context and initialize it */ 219 | if (!(verify_ctx = X509_STORE_CTX_new ())) { 220 | crypto_error_set(error, 1, 0, "error creating X509_STORE_CTX object"); 221 | goto out; 222 | } 223 | /* X509_STORE_CTX_init did not return an error condition in prior versions */ 224 | if (X509_STORE_CTX_init (verify_ctx, store, x509, ctx->stack) != 1) { 225 | crypto_error_set(error, 1, 0, "error intializing verification context"); 226 | goto out; 227 | } 228 | 229 | /* verify the certificate */ 230 | if (X509_verify_cert(verify_ctx) != 1) { 231 | ERR_print_errors_fp(stderr); 232 | crypto_error_set(error, 2, 0, "error verifying the certificate " 233 | "chain"); 234 | goto out; 235 | } 236 | 237 | ret = 0; 238 | 239 | out: 240 | if (lookup) 241 | X509_LOOKUP_free(lookup); 242 | if (store) 243 | X509_STORE_free(store); 244 | if (verify_ctx) 245 | X509_STORE_CTX_free(verify_ctx); 246 | return ret; 247 | } 248 | 249 | unsigned char *crypto_decrypt_signature(crypto_ctx *ctx, 250 | const unsigned char *sig_data, 251 | size_t sig_len, 252 | size_t *out_len, 253 | unsigned int padding, 254 | crypto_error **error) 255 | { 256 | X509 *x509; 257 | EVP_PKEY *pkey = NULL; 258 | RSA *rsa; 259 | unsigned char *hash = NULL; 260 | int tmp_len = -1, ossl_pad; 261 | 262 | *out_len = 0; 263 | 264 | if (!ctx) { 265 | crypto_error_set(error, 1, 0, "invalid crypto context"); 266 | return NULL; 267 | } 268 | 269 | x509 = sk_X509_value(ctx->stack, sk_X509_num(ctx->stack) - 1); 270 | if (x509 == NULL) { 271 | ERR_print_errors_fp (stderr); 272 | crypto_error_set(error, 1, 0, "no certificates in the stack"); 273 | return NULL; 274 | } 275 | 276 | pkey = X509_get_pubkey(x509); 277 | if (pkey == NULL) { 278 | ERR_print_errors_fp (stderr); 279 | crypto_error_set(error, 1, 0, "error getting certificate public key"); 280 | return NULL; 281 | } 282 | 283 | rsa = EVP_PKEY_get1_RSA(pkey); 284 | if (rsa == NULL) { 285 | ERR_print_errors_fp (stderr); 286 | crypto_error_set(error, 1, 0, "error getting public key RSA"); 287 | goto out; 288 | } 289 | 290 | hash = calloc(1, RSA_size(rsa)); 291 | if (!hash) { 292 | crypto_error_set(error, 1, 0, "not enough memory to decrypt signature"); 293 | goto out; 294 | } 295 | 296 | switch (padding) { 297 | case CRYPTO_PAD_NONE: 298 | ossl_pad = RSA_NO_PADDING; 299 | break; 300 | case CRYPTO_PAD_PKCS1: 301 | ossl_pad = RSA_PKCS1_PADDING; 302 | break; 303 | default: 304 | crypto_error_set(error, 1, 0, "unknown padding mechanism %d", padding); 305 | goto out; 306 | } 307 | 308 | tmp_len = RSA_public_decrypt(sig_len, sig_data, hash, rsa, ossl_pad); 309 | if (tmp_len > 0) { 310 | *out_len = (size_t) tmp_len; 311 | } else { 312 | ERR_print_errors_fp (stderr); 313 | crypto_error_set(error, 1, 0, "could not decrypt signature"); 314 | free(hash); 315 | hash = NULL; 316 | } 317 | 318 | out: 319 | if (pkey) 320 | EVP_PKEY_free(pkey); 321 | return hash; 322 | } 323 | 324 | -------------------------------------------------------------------------------- /math_group.c: -------------------------------------------------------------------------------- 1 | /* borrowed from isakmpd-20030718 (-; */ 2 | 3 | /* $OpenBSD: math_group.c,v 1.18 2003/06/03 14:28:16 ho Exp $ */ 4 | /* $EOM: math_group.c,v 1.25 2000/04/07 19:53:26 niklas Exp $ */ 5 | 6 | /* 7 | * Copyright (c) 1998 Niels Provos. All rights reserved. 8 | * Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | /* 32 | * This code was written under funding by Ericsson Radio Systems. 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | 43 | #include "math_group.h" 44 | 45 | /* We do not want to export these definitions. */ 46 | static void modp_free(struct group *); 47 | static struct group *modp_clone(struct group *, struct group *); 48 | static void modp_init(struct group *); 49 | 50 | static int modp_getlen(struct group *); 51 | static void modp_getraw(struct group *, gcry_mpi_t, unsigned char *); 52 | static int modp_setraw(struct group *, gcry_mpi_t, unsigned char *, int); 53 | static int modp_setrandom(struct group *, gcry_mpi_t); 54 | static int modp_operation(struct group *, gcry_mpi_t, gcry_mpi_t, gcry_mpi_t); 55 | 56 | /* 57 | * This module provides access to the operations on the specified group 58 | * and is absolutly free of any cryptographic devices. This is math :-). 59 | */ 60 | 61 | /* Describe preconfigured MODP groups */ 62 | 63 | /* 64 | * The Generalized Number Field Sieve has an asymptotic running time 65 | * of: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3))), where q is the 66 | * group order, e.g. q = 2**768. 67 | */ 68 | 69 | static const struct modp_dscr oakley_modp[] = { 70 | { 71 | OAKLEY_GRP_1, 72, /* This group is insecure, only sufficient for DES */ 72 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 73 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 74 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 75 | "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF", 76 | "2" 77 | }, 78 | { 79 | OAKLEY_GRP_2, 82, /* This group is a bit better */ 80 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 81 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 82 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 83 | "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 84 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" 85 | "FFFFFFFFFFFFFFFF", 86 | "2" 87 | }, 88 | { 89 | OAKLEY_GRP_5, 102, /* This group is yet a bit better, but non-standard */ 90 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 91 | "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 92 | "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 93 | "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 94 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 95 | "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 96 | "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 97 | "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF", 98 | "2" 99 | }, 100 | }; 101 | 102 | /* XXX I want to get rid of the casting here. */ 103 | static struct group groups[] = { 104 | { 105 | MODP, OAKLEY_GRP_1, 0, NULL, &oakley_modp[0], NULL, NULL, NULL, NULL, NULL, 106 | (int (*)(struct group *))modp_getlen, 107 | (void (*)(struct group *, void *, unsigned char *))modp_getraw, 108 | (int (*)(struct group *, void *, unsigned char *, int))modp_setraw, 109 | (int (*)(struct group *, void *))modp_setrandom, 110 | (int (*)(struct group *, void *, void *, void *))modp_operation 111 | }, 112 | { 113 | MODP, OAKLEY_GRP_2, 0, NULL, &oakley_modp[1], NULL, NULL, NULL, NULL, NULL, 114 | (int (*)(struct group *))modp_getlen, 115 | (void (*)(struct group *, void *, unsigned char *))modp_getraw, 116 | (int (*)(struct group *, void *, unsigned char *, int))modp_setraw, 117 | (int (*)(struct group *, void *))modp_setrandom, 118 | (int (*)(struct group *, void *, void *, void *))modp_operation 119 | }, 120 | { 121 | MODP, OAKLEY_GRP_5, 0, NULL, &oakley_modp[2], NULL, NULL, NULL, NULL, NULL, 122 | (int (*)(struct group *))modp_getlen, 123 | (void (*)(struct group *, void *, unsigned char *))modp_getraw, 124 | (int (*)(struct group *, void *, unsigned char *, int))modp_setraw, 125 | (int (*)(struct group *, void *))modp_setrandom, 126 | (int (*)(struct group *, void *, void *, void *))modp_operation 127 | }, 128 | }; 129 | 130 | /* 131 | * Initialize the group structure for later use, 132 | * this is done by converting the values given in the describtion 133 | * and converting them to their native representation. 134 | */ 135 | void group_init(void) 136 | { 137 | int i; 138 | 139 | for (i = sizeof(groups) / sizeof(groups[0]) - 1; i >= 0; i--) { 140 | assert(groups[i].type == MODP); 141 | modp_init(&groups[i]); /* Initialize an over GF(p) */ 142 | } 143 | } 144 | 145 | struct group *group_get(int id) 146 | { 147 | struct group *new, *clone; 148 | 149 | assert(id >= 1); 150 | assert(id <= (int)(sizeof(groups) / sizeof(groups[0]))); 151 | 152 | clone = &groups[id - 1]; 153 | 154 | new = malloc(sizeof *new); 155 | assert(new); 156 | 157 | assert(clone->type == MODP); 158 | new = modp_clone(new, clone); 159 | return new; 160 | } 161 | 162 | void group_free(struct group *grp) 163 | { 164 | assert(grp->type == MODP); 165 | modp_free(grp); 166 | free(grp); 167 | } 168 | 169 | static struct group *modp_clone(struct group *new, struct group *clone) 170 | { 171 | struct modp_group *new_grp, *clone_grp = clone->group; 172 | 173 | new_grp = malloc(sizeof *new_grp); 174 | assert(new_grp); 175 | 176 | memcpy(new, clone, sizeof(struct group)); 177 | 178 | new->group = new_grp; 179 | new_grp->p = gcry_mpi_copy(clone_grp->p); 180 | new_grp->gen = gcry_mpi_copy(clone_grp->gen); 181 | 182 | new_grp->a = gcry_mpi_new(clone->bits); 183 | new_grp->b = gcry_mpi_new(clone->bits); 184 | new_grp->c = gcry_mpi_new(clone->bits); 185 | 186 | new->gen = new_grp->gen; 187 | new->a = new_grp->a; 188 | new->b = new_grp->b; 189 | new->c = new_grp->c; 190 | 191 | return new; 192 | } 193 | 194 | static void modp_free(struct group *old) 195 | { 196 | struct modp_group *grp = old->group; 197 | 198 | gcry_mpi_release(grp->p); 199 | gcry_mpi_release(grp->gen); 200 | gcry_mpi_release(grp->a); 201 | gcry_mpi_release(grp->b); 202 | gcry_mpi_release(grp->c); 203 | 204 | free(grp); 205 | } 206 | 207 | static void modp_init(struct group *group) 208 | { 209 | const struct modp_dscr *dscr = group->group_dscr; 210 | struct modp_group *grp; 211 | 212 | grp = malloc(sizeof *grp); 213 | assert(grp); 214 | 215 | group->bits = dscr->bits; 216 | 217 | gcry_mpi_scan(&grp->p, GCRYMPI_FMT_HEX, (const unsigned char*)dscr->prime, 0, NULL); 218 | gcry_mpi_scan(&grp->gen, GCRYMPI_FMT_HEX, (const unsigned char *)dscr->gen, 0, NULL); 219 | 220 | grp->a = gcry_mpi_new(group->bits); 221 | grp->b = gcry_mpi_new(group->bits); 222 | grp->c = gcry_mpi_new(group->bits); 223 | 224 | group->gen = grp->gen; 225 | group->a = grp->a; 226 | group->b = grp->b; 227 | group->c = grp->c; 228 | 229 | group->group = grp; 230 | } 231 | 232 | static int modp_getlen(struct group *group) 233 | { 234 | struct modp_group *grp = (struct modp_group *)group->group; 235 | 236 | return (gcry_mpi_get_nbits(grp->p) + 7) / 8; 237 | } 238 | 239 | static void modp_getraw(struct group *grp, gcry_mpi_t v, unsigned char *d) 240 | { 241 | size_t l, l2; 242 | unsigned char *tmp; 243 | int ret; 244 | 245 | l = grp->getlen(grp); 246 | ret = gcry_mpi_aprint(GCRYMPI_FMT_STD, &tmp, &l2, v); 247 | memcpy(d, tmp + (l2 - l), l); 248 | gcry_free(tmp); 249 | #if 0 250 | { 251 | char *p; 252 | gcry_mpi_aprint(GCRYMPI_FMT_HEX, (void **)&p, NULL, v); 253 | printf("export %d - %d(%d):\n%s\n", l, l2, ret, p); 254 | gcry_free(p); 255 | } 256 | #endif 257 | } 258 | 259 | static int modp_setraw(struct group *grp, gcry_mpi_t d, unsigned char *s, int l) 260 | { 261 | int i; 262 | 263 | grp = NULL; /* unused */ 264 | 265 | gcry_mpi_set_ui(d, 0); 266 | for (i = 0; i < l; i++) { 267 | gcry_mpi_mul_2exp(d, d, 8); 268 | gcry_mpi_add_ui(d, d, s[i]); 269 | } 270 | #if 0 271 | { 272 | char *p; 273 | gcry_mpi_aprint(GCRYMPI_FMT_HEX, (void **)&p, NULL, d); 274 | printf("import %d:\n%s\n", l, p); 275 | gcry_free(p); 276 | } 277 | #endif 278 | return 0; 279 | } 280 | 281 | static int modp_setrandom(struct group *grp, gcry_mpi_t d) 282 | { 283 | int i, l = grp->getlen(grp); 284 | uint32_t tmp = 0; 285 | 286 | gcry_mpi_set_ui(d, 0); 287 | 288 | for (i = 0; i < l; i++) { 289 | if (i % 4) 290 | gcry_randomize((unsigned char *)&tmp, sizeof(tmp), GCRY_STRONG_RANDOM); 291 | 292 | gcry_mpi_mul_2exp(d, d, 8); 293 | gcry_mpi_add_ui(d, d, tmp & 0xFF); 294 | tmp >>= 8; 295 | } 296 | return 0; 297 | } 298 | 299 | static int modp_operation(struct group *group, gcry_mpi_t d, gcry_mpi_t a, gcry_mpi_t e) 300 | { 301 | struct modp_group *grp = (struct modp_group *)group->group; 302 | 303 | gcry_mpi_powm(d, a, e, grp->p); 304 | return 0; 305 | } 306 | -------------------------------------------------------------------------------- /isakmp.h: -------------------------------------------------------------------------------- 1 | /* ISAKMP constants. 2 | Copyright (C) 2002 Geoffrey Keating 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | 18 | $Id$ 19 | */ 20 | 21 | #ifndef __ISAKMP_H__ 22 | #define __ISAKMP_H__ 23 | 24 | /* Flag bits for header. */ 25 | #define ISAKMP_FLAG_E 0x1 26 | #define ISAKMP_FLAG_C 0x2 27 | #define ISAKMP_FLAG_A 0x4 28 | 29 | /* Payload types */ 30 | enum isakmp_payload_enum { 31 | ISAKMP_PAYLOAD_NONE = 0, /* RFC 2408 */ 32 | ISAKMP_PAYLOAD_SA, /* RFC 2408, Security Association */ 33 | ISAKMP_PAYLOAD_P, /* RFC 2408, Proposal */ 34 | ISAKMP_PAYLOAD_T, /* RFC 2408, Transform */ 35 | ISAKMP_PAYLOAD_KE, /* RFC 2408, Key Exchange */ 36 | ISAKMP_PAYLOAD_ID, /* RFC 2408, Identification */ 37 | ISAKMP_PAYLOAD_CERT, /* RFC 2408, Certificate */ 38 | ISAKMP_PAYLOAD_CR, /* RFC 2408, Certificate Request */ 39 | ISAKMP_PAYLOAD_HASH, /* RFC 2408, Hash */ 40 | ISAKMP_PAYLOAD_SIG, /* RFC 2408, Signature */ 41 | ISAKMP_PAYLOAD_NONCE, /* RFC 2408, Nonce */ 42 | ISAKMP_PAYLOAD_N, /* RFC 2408, Notification */ 43 | ISAKMP_PAYLOAD_D, /* RFC 2408, Delete */ 44 | ISAKMP_PAYLOAD_VID, /* RFC 2408, Vendor ID */ 45 | ISAKMP_PAYLOAD_MODECFG_ATTR, 46 | ISAKMP_PAYLOAD_SAK, /* RFC 3547, SA KEK */ 47 | ISAKMP_PAYLOAD_SAT, /* RFC 3547, SA TEK */ 48 | ISAKMP_PAYLOAD_KD, /* RFC 3547, Key Download */ 49 | ISAKMP_PAYLOAD_SEQNO, /* RFC 3547, Sequence number */ 50 | ISAKMP_PAYLOAD_POP, /* RFC 3547, Proof of Possession */ 51 | ISAKMP_PAYLOAD_NAT_D, /* RFC 3947, NAT Discovery */ 52 | ISAKMP_PAYLOAD_NAT_OA, /* RFC 3947, NAT Original Address */ 53 | ISAKMP_PAYLOAD_NAT_D_OLD = 0x82, 54 | ISAKMP_PAYLOAD_FRAG = 0x84 55 | }; 56 | 57 | /* Exchange types. */ 58 | enum isakmp_exchange_enum { 59 | ISAKMP_EXCHANGE_NONE = 0, 60 | ISAKMP_EXCHANGE_BASE, 61 | ISAKMP_EXCHANGE_IDENTITY, 62 | ISAKMP_EXCHANGE_AUTH_ONLY, 63 | ISAKMP_EXCHANGE_AGGRESSIVE, 64 | ISAKMP_EXCHANGE_INFORMATIONAL, 65 | ISAKMP_EXCHANGE_MODECFG_TRANSACTION, 66 | ISAKMP_EXCHANGE_IKE_QUICK = 32, 67 | ISAKMP_EXCHANGE_IKE_NEW_GROUP 68 | }; 69 | 70 | /* DOI types. */ 71 | enum isakmp_doi_enum { 72 | ISAKMP_DOI_GENERIC = 0, 73 | ISAKMP_DOI_IPSEC 74 | }; 75 | 76 | /* Notify message types (error: 1-16383; status: 16384-65535). */ 77 | enum isakmp_notify_enum { 78 | ISAKMP_N_INVALID_PAYLOAD_TYPE = 1, 79 | ISAKMP_N_DOI_NOT_SUPPORTED, 80 | ISAKMP_N_SITUATION_NOT_SUPPORTED, 81 | ISAKMP_N_INVALID_COOKIE, 82 | ISAKMP_N_INVALID_MAJOR_VERSION, 83 | ISAKMP_N_INVALID_MINOR_VERSION, 84 | ISAKMP_N_INVALID_EXCHANGE_TYPE, 85 | ISAKMP_N_INVALID_FLAGS, 86 | ISAKMP_N_INVALID_MESSAGE_ID, 87 | ISAKMP_N_INVALID_PROTOCOL_ID, 88 | ISAKMP_N_INVALID_SPI, 89 | ISAKMP_N_INVALID_TRANSFORM_ID, 90 | ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED, 91 | ISAKMP_N_NO_PROPOSAL_CHOSEN, 92 | ISAKMP_N_BAD_PROPOSAL_SYNTAX, 93 | ISAKMP_N_PAYLOAD_MALFORMED, 94 | ISAKMP_N_INVALID_KEY_INFORMATION, 95 | ISAKMP_N_INVALID_ID_INFORMATION, 96 | ISAKMP_N_INVALID_CERT_ENCODING, 97 | ISAKMP_N_INVALID_CERTIFICATE, 98 | ISAKMP_N_CERT_TYPE_UNSUPPORTED, 99 | ISAKMP_N_INVALID_CERT_AUTHORITY, 100 | ISAKMP_N_INVALID_HASH_INFORMATION, 101 | ISAKMP_N_AUTHENTICATION_FAILED, 102 | ISAKMP_N_INVALID_SIGNATURE, 103 | ISAKMP_N_ADDRESS_NOTIFICATION, 104 | ISAKMP_N_NOTIFY_SA_LIFETIME, 105 | ISAKMP_N_CERTIFICATE_UNAVAILABLE, 106 | ISAKMP_N_UNSUPPORTED_EXCHANGE_TYPE, 107 | ISAKMP_N_UNEQUAL_PAYLOAD_LENGTHS, 108 | ISAKMP_N_CONNECTED = 16384, 109 | ISAKMP_N_IPSEC_RESPONDER_LIFETIME = 24576, 110 | ISAKMP_N_IPSEC_REPLAY_STATUS, 111 | ISAKMP_N_IPSEC_INITIAL_CONTACT, 112 | ISAKMP_N_CISCO_HELLO = 30000, 113 | ISAKMP_N_CISCO_WWTEBR, 114 | ISAKMP_N_CISCO_SHUT_UP, 115 | ISAKMP_N_IOS_KEEP_ALIVE_REQ = 32768, 116 | ISAKMP_N_IOS_KEEP_ALIVE_ACK, 117 | ISAKMP_N_R_U_THERE = 36136, 118 | ISAKMP_N_R_U_THERE_ACK, 119 | ISAKMP_N_CISCO_LOAD_BALANCE = 40501, 120 | ISAKMP_N_CISCO_PRESHARED_KEY_HASH = 40503 121 | }; 122 | 123 | /* Delete with reason values */ 124 | /* Note: The values are random, i.e. we don't know them yet */ 125 | enum dwr_ike_delete { 126 | IKE_DELETE_SERVER_SHUTDOWN = 0, /* Peer has been shut down */ 127 | IKE_DELETE_SERVER_REBOOT, /* Peer has been rebooted. */ 128 | IKE_DELETE_MAX_CONNECT_TIME, /* Maximum configured connection time exceeded. */ 129 | IKE_DELETE_BY_USER_COMMAND, /* Manually disconnected by administrator. */ 130 | IKE_DELETE_BY_ERROR, /* Connectivity to Client lost. */ 131 | IKE_DELETE_NO_ERROR, /* Unknown error. */ 132 | IKE_DELETE_IDLE_TIMEOUT, /* Maximum idle time for session exceeded. */ 133 | IKE_DELETE_P2_PROPOSAL_MISMATCH, /* Policy negotiation failed */ 134 | IKE_DELETE_FIREWALL_MISMATCH, /* Firewall policy mismatch. */ 135 | IKE_DELETE_CERT_EXPIRED, /* Certificates used with this connection entry have expired. */ 136 | IKE_DELETE_BY_EXPIRED_LIFETIME, /* Maximum configured lifetime exceeded. */ 137 | DEL_REASON_RESET_SADB /* (found in vpnclient log file) */ 138 | }; 139 | 140 | /* Certificate types. */ 141 | enum isakmp_certificate_enum { 142 | ISAKMP_CERT_NONE = 0, 143 | ISAKMP_CERT_PKCS7_X509, 144 | ISAKMP_CERT_PGP, 145 | ISAKMP_CERT_DNS_SIG_KEY, 146 | ISAKMP_CERT_X509_SIG, 147 | ISAKMP_CERT_X509_KEX_EXCHANGE, 148 | ISAKMP_CERT_KERBEROS_TOKENS, 149 | ISAKMP_CERT_CRL, 150 | ISAKMP_CERT_ARL, 151 | ISAKMP_CERT_SPKI, 152 | ISAKMP_CERT_X509_ATTRIBUTE 153 | }; 154 | 155 | /* IKE attribute types. */ 156 | enum ike_attr_enum { 157 | IKE_ATTRIB_ENC = 1, 158 | IKE_ATTRIB_HASH, 159 | IKE_ATTRIB_AUTH_METHOD, 160 | IKE_ATTRIB_GROUP_DESC, 161 | IKE_ATTRIB_GROUP_TYPE, 162 | IKE_ATTRIB_GROUP_PRIME, 163 | IKE_ATTRIB_GROUP_GEN_1, 164 | IKE_ATTRIB_GROUP_GEN_2, 165 | IKE_ATTRIB_GROUP_CURVE_A, 166 | IKE_ATTRIB_GROUP_CURVE_B, 167 | IKE_ATTRIB_LIFE_TYPE, 168 | IKE_ATTRIB_LIFE_DURATION, 169 | IKE_ATTRIB_PRF, 170 | IKE_ATTRIB_KEY_LENGTH, 171 | IKE_ATTRIB_FIELD_SIZE, 172 | IKE_ATTRIB_GROUP_ORDER, 173 | IKE_ATTRIB_BLOCK_SIZE, 174 | IKE_ATTRIB_NORTEL_UNKNOWN = 32767 175 | }; 176 | 177 | /* IKE encryption algorithm IDs. */ 178 | enum ike_enc_enum { 179 | IKE_ENC_NO_CBC = 0, 180 | IKE_ENC_DES_CBC, 181 | IKE_ENC_IDEA_CBC, 182 | IKE_ENC_BLOWFISH_CBC, 183 | IKE_ENC_RC5_R16_B16_CBC, 184 | IKE_ENC_3DES_CBC, 185 | IKE_ENC_CAST_CBC, 186 | IKE_ENC_AES_CBC 187 | }; 188 | 189 | /* IKE hash algorithm IDs. */ 190 | enum ike_hash_enum { 191 | IKE_HASH_MD5 = 1, 192 | IKE_HASH_SHA, 193 | IKE_HASH_TIGER, 194 | IKE_HASH_SHA2_256, 195 | IKE_HASH_SHA2_384, 196 | IKE_HASH_SHA2_512 197 | }; 198 | 199 | /* IKE authentication method IDs. */ 200 | enum ike_auth_enum { 201 | IKE_AUTH_PRESHARED = 1, 202 | IKE_AUTH_DSS, 203 | IKE_AUTH_RSA_SIG, 204 | IKE_AUTH_RSA_ENC, 205 | IKE_AUTH_RSA_ENC_2, 206 | IKE_AUTH_EL_GAMAL_ENC, 207 | IKE_AUTH_EL_GAMAL_ENC_REV, 208 | IKE_AUTH_ECDSA_SIG, 209 | IKE_AUTH_HybridInitRSA = 64221, 210 | IKE_AUTH_HybridRespRSA, 211 | IKE_AUTH_HybridInitDSS, 212 | IKE_AUTH_HybridRespDSS, 213 | IKE_AUTH_XAUTHInitPreShared = 65001, 214 | IKE_AUTH_XAUTHRespPreShared, 215 | IKE_AUTH_XAUTHInitDSS, 216 | IKE_AUTH_XAUTHRespDSS, 217 | IKE_AUTH_XAUTHInitRSA, 218 | IKE_AUTH_XAUTHRespRSA, 219 | IKE_AUTH_XAUTHInitRSAEncryption, 220 | IKE_AUTH_XAUTHRespRSAEncryption, 221 | IKE_AUTH_XAUTHInitRSARevisedEncryption, 222 | IKE_AUTH_XAUTHRespRSARevisedEncryption 223 | }; 224 | 225 | /* IKE group IDs. */ 226 | enum ike_group_enum { 227 | IKE_GROUP_MODP_768 = 1, 228 | IKE_GROUP_MODP_1024, 229 | IKE_GROUP_EC2N_155, 230 | IKE_GROUP_EC2N_185, 231 | IKE_GROUP_MODP_1536, 232 | IKE_GROUP_EC2N_163sect, 233 | IKE_GROUP_EC2N_163K, 234 | IKE_GROUP_EC2N_283sect, 235 | IKE_GROUP_EC2N_283K, 236 | IKE_GROUP_EC2N_409sect, 237 | IKE_GROUP_EC2N_409K, 238 | IKE_GROUP_EC2N_571sect, 239 | IKE_GROUP_EC2N_571K 240 | }; 241 | 242 | /* IKE group type IDs. */ 243 | enum ike_group_type_enum { 244 | IKE_GROUP_TYPE_MODP = 1, 245 | IKE_GROUP_TYPE_ECP, 246 | IKE_GROUP_TYPE_EC2N 247 | }; 248 | 249 | /* IKE life type IDs. */ 250 | enum ike_life_enum { 251 | IKE_LIFE_TYPE_SECONDS = 1, 252 | IKE_LIFE_TYPE_K 253 | }; 254 | 255 | /* IPSEC situation masks. */ 256 | enum isakmp_ipsec_sit_enum { 257 | ISAKMP_IPSEC_SIT_IDENTITY_ONLY = 0x1, 258 | ISAKMP_IPSEC_SIT_SECRECY = 0x2, 259 | ISAKMP_IPSEC_SIT_INTEGRITY = 0x4 260 | }; 261 | 262 | /* IPSEC Identification types. */ 263 | enum isakmp_ipsec_id_enum { 264 | ISAKMP_IPSEC_ID_RESERVED = 0, 265 | ISAKMP_IPSEC_ID_IPV4_ADDR, 266 | ISAKMP_IPSEC_ID_FQDN, 267 | ISAKMP_IPSEC_ID_USER_FQDN, 268 | ISAKMP_IPSEC_ID_IPV4_ADDR_SUBNET, 269 | ISAKMP_IPSEC_ID_IPV6_ADDR, 270 | ISAKMP_IPSEC_ID_IPV6_ADDR_SUBNET, 271 | ISAKMP_IPSEC_ID_IPV4_ADDR_RANGE, 272 | ISAKMP_IPSEC_ID_IPV6_ADDR_RANGE, 273 | ISAKMP_IPSEC_ID_DER_ASN1_DN, 274 | ISAKMP_IPSEC_ID_DER_ASN1_GN, 275 | ISAKMP_IPSEC_ID_KEY_ID 276 | }; 277 | 278 | /* IPSEC protocol IDs. */ 279 | enum isakmp_ipsec_proto_enum { 280 | ISAKMP_IPSEC_PROTO_RESERVED = 0, 281 | ISAKMP_IPSEC_PROTO_ISAKMP, 282 | ISAKMP_IPSEC_PROTO_IPSEC_AH, 283 | ISAKMP_IPSEC_PROTO_IPSEC_ESP, 284 | ISAKMP_IPSEC_PROTO_IPCOMP, 285 | ISAKMP_IPSEC_PROTO_MODECFG = 512 /* hack for simplicity in debug code */ 286 | }; 287 | 288 | /* IPSEC transform IDs. */ 289 | enum isakmp_ipsec_key_enum { 290 | ISAKMP_IPSEC_KEY_RESERVED = 0, 291 | ISAKMP_IPSEC_KEY_IKE 292 | }; 293 | 294 | /* IPSEC AH IDs. */ 295 | enum isakmp_ipsec_ah_enum { 296 | ISAKMP_IPSEC_AH_RESERVED = 0, 297 | ISAKMP_IPSEC_AH_MD5 = 2, 298 | ISAKMP_IPSEC_AH_SHA, 299 | ISAKMP_IPSEC_AH_DES, 300 | ISAKMP_IPSEC_AH_SHA2_256, 301 | ISAKMP_IPSEC_AH_SHA2_384, 302 | ISAKMP_IPSEC_AH_SHA2_512, 303 | ISAKMP_IPSEC_AH_RIPEMD 304 | }; 305 | 306 | /* IPSEC ESP IDs. */ 307 | enum isakmp_ipsec_esp_enum { 308 | ISAKMP_IPSEC_ESP_RESERVED = 0, 309 | ISAKMP_IPSEC_ESP_DES_IV64, 310 | ISAKMP_IPSEC_ESP_DES, 311 | ISAKMP_IPSEC_ESP_3DES, 312 | ISAKMP_IPSEC_ESP_RC5, 313 | ISAKMP_IPSEC_ESP_IDEA, 314 | ISAKMP_IPSEC_ESP_CAST, 315 | ISAKMP_IPSEC_ESP_BLOWFISH, 316 | ISAKMP_IPSEC_ESP_3IDEA, 317 | ISAKMP_IPSEC_ESP_DES_IV32, 318 | ISAKMP_IPSEC_ESP_RC4, 319 | ISAKMP_IPSEC_ESP_NULL, 320 | ISAKMP_IPSEC_ESP_AES, 321 | ISAKMP_IPSEC_ESP_AES_128_CTR, 322 | ISAKMP_IPSEC_ESP_AES_MARS = 249, 323 | ISAKMP_IPSEC_ESP_AES_RC6, 324 | ISAKMP_IPSEC_ESP_AES_RIJNDAEL, 325 | ISAKMP_IPSEC_ESP_AES_SERPENT, 326 | ISAKMP_IPSEC_ESP_AES_TWOFISH 327 | }; 328 | 329 | /* IPSEC attribute types. */ 330 | enum isakmp_ipsec_attr_enum { 331 | ISAKMP_IPSEC_ATTRIB_SA_LIFE_TYPE = 1, 332 | ISAKMP_IPSEC_ATTRIB_SA_LIFE_DURATION, 333 | ISAKMP_IPSEC_ATTRIB_GROUP_DESC, 334 | ISAKMP_IPSEC_ATTRIB_ENCAP_MODE, 335 | ISAKMP_IPSEC_ATTRIB_AUTH_ALG, 336 | ISAKMP_IPSEC_ATTRIB_KEY_LENGTH, 337 | ISAKMP_IPSEC_ATTRIB_KEY_ROUNDS, 338 | ISAKMP_IPSEC_ATTRIB_COMP_DICT_SIZE, 339 | ISAKMP_IPSEC_ATTRIB_COMP_PRIVATE_ALG, 340 | ISAKMP_IPSEC_ATTRIB_ECN_TUNNEL 341 | }; 342 | 343 | /* IPSEC compression IDs. */ 344 | enum isakmp_ipsec_ipcomp_enum { 345 | ISAKMP_IPSEC_IPCOMP_RESERVED = 0, 346 | ISAKMP_IPSEC_IPCOMP_OUI, 347 | ISAKMP_IPSEC_IPCOMP_DEFLATE, 348 | ISAKMP_IPSEC_IPCOMP_LZS, 349 | ISAKMP_IPSEC_IPCOMP_V42BIS 350 | }; 351 | 352 | /* IPSEC lifetime attribute values. */ 353 | enum ipsec_life_enum { 354 | IPSEC_LIFE_SECONDS = 1, 355 | IPSEC_LIFE_K 356 | }; 357 | 358 | /* IPSEC encapsulation attribute numbers. */ 359 | enum ipsec_encap_enum { 360 | IPSEC_ENCAP_TUNNEL = 1, 361 | IPSEC_ENCAP_TRANSPORT, 362 | IPSEC_ENCAP_UDP_TUNNEL, 363 | IPSEC_ENCAP_UDP_TRANSPORT, 364 | IPSEC_ENCAP_UDP_TUNNEL_OLD = 61443, 365 | IPSEC_ENCAP_UDP_TRANSPORT_OLD 366 | }; 367 | 368 | /* IPSEC authentication attribute numbers. */ 369 | enum ipsec_auth_enum { 370 | IPSEC_AUTH_HMAC_MD5 = 1, 371 | IPSEC_AUTH_HMAC_SHA, 372 | IPSEC_AUTH_DES_MAC, 373 | IPSEC_AUTH_KPDK 374 | }; 375 | 376 | /* Other numbers. */ 377 | #define ISAKMP_COOKIE_LENGTH 8 378 | #define ISAKMP_VERSION 0x10 379 | /* offsets */ 380 | #define ISAKMP_EXCHANGE_TYPE_O 18 381 | #define ISAKMP_I_COOKIE_O 0 382 | #define ISAKMP_R_COOKIE_O 8 383 | #define ISAKMP_MESSAGE_ID_O 20 384 | #define ISAKMP_PAYLOAD_O 28 385 | 386 | /* defined in vpnc.c */ 387 | extern const unsigned char VID_XAUTH[]; 388 | extern const unsigned char VID_DPD[]; 389 | extern const unsigned char VID_UNITY[]; 390 | extern const unsigned char VID_UNKNOWN[]; 391 | extern const unsigned char VID_NATT_00[]; 392 | extern const unsigned char VID_NATT_01[]; 393 | extern const unsigned char VID_NATT_02[]; 394 | extern const unsigned char VID_NATT_02N[]; 395 | extern const unsigned char VID_NATT_RFC[]; 396 | 397 | /* Support for draft-ietf-ipsec-isakmp-mode-cfg-05.txt (yuk). */ 398 | enum isakmp_modecfg_cfg_enum { 399 | ISAKMP_MODECFG_CFG_REQUEST = 1, 400 | ISAKMP_MODECFG_CFG_REPLY, 401 | ISAKMP_MODECFG_CFG_SET, 402 | ISAKMP_MODECFG_CFG_ACK 403 | }; 404 | 405 | enum isakmp_modecfg_attrib_enum { 406 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_ADDRESS = 1, 407 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_NETMASK, 408 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_DNS, 409 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_NBNS, 410 | ISAKMP_MODECFG_ATTRIB_INTERNAL_ADDRESS_EXPIRY, 411 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_DHCP, 412 | ISAKMP_MODECFG_ATTRIB_APPLICATION_VERSION, 413 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP6_ADDRESS, 414 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP6_NETMASK, 415 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP6_DNS, 416 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP6_NBNS, 417 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP6_DHCP, 418 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_SUBNET, 419 | ISAKMP_MODECFG_ATTRIB_SUPPORTED_ATTRIBUTES, 420 | ISAKMP_MODECFG_ATTRIB_INTERNAL_IP6_SUBNET, 421 | ISAKMP_MODECFG_ATTRIB_CISCO_UNKNOWN_0X0015 = 0x0015, 422 | ISAKMP_XAUTH_06_ATTRIB_TYPE = 0x4088, 423 | ISAKMP_XAUTH_06_ATTRIB_USER_NAME, 424 | ISAKMP_XAUTH_06_ATTRIB_USER_PASSWORD, 425 | ISAKMP_XAUTH_06_ATTRIB_PASSCODE, 426 | ISAKMP_XAUTH_06_ATTRIB_MESSAGE, 427 | ISAKMP_XAUTH_06_ATTRIB_CHALLENGE, 428 | ISAKMP_XAUTH_06_ATTRIB_DOMAIN, 429 | ISAKMP_XAUTH_06_ATTRIB_STATUS, 430 | ISAKMP_XAUTH_06_ATTRIB_NEXT_PIN, 431 | ISAKMP_XAUTH_06_ATTRIB_ANSWER, /* TYPE .. ANSWER is excluded from dump */ 432 | ISAKMP_MODECFG_ATTRIB_CISCO_BANNER = 0x7000, 433 | ISAKMP_MODECFG_ATTRIB_CISCO_SAVE_PW, 434 | ISAKMP_MODECFG_ATTRIB_CISCO_DEF_DOMAIN, 435 | ISAKMP_MODECFG_ATTRIB_CISCO_SPLIT_DNS, 436 | ISAKMP_MODECFG_ATTRIB_CISCO_SPLIT_INC, 437 | ISAKMP_MODECFG_ATTRIB_CISCO_UDP_ENCAP_PORT, 438 | ISAKMP_MODECFG_ATTRIB_CISCO_UNKNOWN, /* whatever 0x7006 is... */ 439 | ISAKMP_MODECFG_ATTRIB_CISCO_DO_PFS, 440 | /* Cisco Ext: Smartcard Disconnect */ 441 | /* Cisco Ext: IKE_CFG_FWTYPE_VENDOR */ 442 | /* Cisco Ext: IKE_CFG_FWTYPE_PRODUCT */ 443 | /* Cisco Ext: IKE_CFG_FWTYPE_CAPABILITIES??? */ 444 | ISAKMP_MODECFG_ATTRIB_CISCO_FW_TYPE, 445 | ISAKMP_MODECFG_ATTRIB_CISCO_BACKUP_SERVER, 446 | ISAKMP_MODECFG_ATTRIB_CISCO_DDNS_HOSTNAME, 447 | ISAKMP_XAUTH_ATTRIB_CISCOEXT_VENDOR = 0x7d88 /* strange cisco things ... need docs! */ 448 | }; 449 | 450 | #endif 451 | -------------------------------------------------------------------------------- /crypto-gnutls.c: -------------------------------------------------------------------------------- 1 | /* IPSec VPN client compatible with Cisco equipment. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; either version 2 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "config.h" 25 | #include "sysdep.h" 26 | #include "crypto.h" 27 | 28 | static int gnutls_initialized = 0; 29 | 30 | #define CERT_STACK_DEPTH 20 31 | 32 | crypto_ctx *crypto_ctx_new(crypto_error **error) 33 | { 34 | crypto_ctx *ctx; 35 | 36 | if (!gnutls_initialized) { 37 | if (gnutls_global_init() != 0) { 38 | crypto_error_set(error, 1, 0, "error initializing gnutls globals"); 39 | return NULL; 40 | } 41 | gnutls_initialized = 1; 42 | } 43 | 44 | ctx = gnutls_calloc(1, sizeof(crypto_ctx)); 45 | if (!ctx) { 46 | crypto_error_set(error, 1, ENOMEM, "not enough memory for crypto context"); 47 | return NULL; 48 | } 49 | 50 | ctx->stack = gnutls_calloc(CERT_STACK_DEPTH, sizeof(gnutls_x509_crt_t)); 51 | if (!ctx->stack) { 52 | crypto_ctx_free(ctx); 53 | crypto_error_set(error, 1, ENOMEM, 54 | "not enough memory for crypto certificate stack"); 55 | ctx = NULL; 56 | } 57 | 58 | return ctx; 59 | } 60 | 61 | void crypto_ctx_free(crypto_ctx *ctx) 62 | { 63 | if (ctx) { 64 | int i; 65 | 66 | for (i = 0; i < ctx->num; i++) 67 | gnutls_x509_crt_deinit(ctx->stack[i]); 68 | gnutls_free(ctx->stack); 69 | memset(ctx, 0, sizeof(crypto_ctx)); 70 | gnutls_free(ctx); 71 | } 72 | } 73 | 74 | unsigned char *crypto_read_cert(const char *path, 75 | size_t *out_len, 76 | crypto_error **error) 77 | { 78 | gnutls_x509_crt_t cert; 79 | unsigned char *data = NULL; 80 | gnutls_datum dt; 81 | size_t fsize = 0; 82 | int err; 83 | 84 | dt.data = crypto_read_file(path, &fsize, error); 85 | if (!dt.data) 86 | return NULL; 87 | 88 | dt.size = (unsigned int) fsize; 89 | if (gnutls_x509_crt_init(&cert) != GNUTLS_E_SUCCESS) { 90 | crypto_error_set(error, 1, ENOMEM, "not enough memory for certificate"); 91 | goto out; 92 | } 93 | 94 | err = gnutls_x509_crt_import(cert, &dt, GNUTLS_X509_FMT_PEM); 95 | if (err != GNUTLS_E_SUCCESS) 96 | err = gnutls_x509_crt_import(cert, &dt, GNUTLS_X509_FMT_DER); 97 | if (err != GNUTLS_E_SUCCESS) { 98 | crypto_error_set(error, 1, 0, "certificate (%s) format unknown", path); 99 | goto out; 100 | } 101 | 102 | *out_len = 10000; 103 | data = malloc(*out_len); 104 | err = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, data, out_len); 105 | if (err != GNUTLS_E_SUCCESS) { 106 | free(data); 107 | *out_len = 0; 108 | crypto_error_set(error, 1, 0, "certificate could not be exported"); 109 | } 110 | 111 | out: 112 | if (dt.data) 113 | gnutls_free(dt.data); 114 | gnutls_x509_crt_deinit(cert); 115 | return data; 116 | } 117 | 118 | int crypto_push_cert(crypto_ctx *ctx, 119 | const unsigned char *data, 120 | size_t len, 121 | crypto_error **error) 122 | { 123 | gnutls_x509_crt_t cert; 124 | gnutls_datum dt; 125 | int err; 126 | 127 | if (!ctx || !data || (len <= 0)) { 128 | crypto_error_set(error, 1, 0, "invalid crypto context or data"); 129 | return 1; 130 | } 131 | 132 | if (ctx->num >= CERT_STACK_DEPTH) { 133 | crypto_error_set(error, 1, 0, "too many certificates in the chain."); 134 | return 1; 135 | } 136 | 137 | gnutls_x509_crt_init (&cert); 138 | 139 | dt.data = (unsigned char *) data; 140 | dt.size = len; 141 | err = gnutls_x509_crt_import (cert, &dt, GNUTLS_X509_FMT_DER); 142 | if (err != GNUTLS_E_SUCCESS) { 143 | gnutls_x509_crt_deinit (cert); 144 | crypto_error_set(error, 1, 0, "failed to decode certificate"); 145 | return 1; 146 | } 147 | 148 | ctx->stack[ctx->num] = cert; 149 | ctx->num++; 150 | return 0; 151 | } 152 | 153 | static int verify_issuer(gnutls_x509_crt_t crt, 154 | gnutls_x509_crt_t issuer, 155 | crypto_error **error) 156 | { 157 | unsigned int output; 158 | time_t now = time (0); 159 | 160 | if (gnutls_x509_crt_verify(crt, &issuer, 1, 0, &output) < 0) { 161 | crypto_error_set(error, 1, 0, "failed to verify against issuer"); 162 | return 1; 163 | } 164 | 165 | if (output & GNUTLS_CERT_INVALID) { 166 | if (output & GNUTLS_CERT_SIGNER_NOT_FOUND) { 167 | crypto_error_set(error, 1, 0, "certificate signer not found"); 168 | return 1; 169 | } 170 | if (output & GNUTLS_CERT_SIGNER_NOT_CA) { 171 | crypto_error_set(error, 1, 0, "certificate signer not a CA"); 172 | return 1; 173 | } 174 | } 175 | 176 | if (gnutls_x509_crt_get_activation_time(crt) > now) { 177 | crypto_error_set(error, 1, 0, "certificate activation in the future"); 178 | return 1; 179 | } 180 | 181 | if (gnutls_x509_crt_get_expiration_time(crt) < now) { 182 | crypto_error_set(error, 1, 0, "certificate expired"); 183 | return 1; 184 | } 185 | 186 | return 0; 187 | } 188 | 189 | static int verify_last(gnutls_x509_crt_t crt, 190 | gnutls_x509_crt_t *ca_list, 191 | size_t ca_list_size, 192 | crypto_error **error) 193 | { 194 | unsigned int output; 195 | time_t now = time (0); 196 | 197 | if (gnutls_x509_crt_verify (crt, ca_list, ca_list_size, 198 | GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, 199 | &output) < 0) { 200 | crypto_error_set(error, 1, 0, "failed to verify against CA list"); 201 | return 1; 202 | } 203 | 204 | if (output & GNUTLS_CERT_INVALID) { 205 | if (output & GNUTLS_CERT_SIGNER_NOT_CA) { 206 | crypto_error_set(error, 1, 0, "certificate signer not a CA"); 207 | return 1; 208 | } 209 | } 210 | 211 | if (gnutls_x509_crt_get_activation_time(crt) > now) { 212 | crypto_error_set(error, 1, 0, "certificate activation in the future"); 213 | return 1; 214 | } 215 | 216 | if (gnutls_x509_crt_get_expiration_time(crt) < now) { 217 | crypto_error_set(error, 1, 0, "certificate expired"); 218 | return 1; 219 | } 220 | 221 | return 0; 222 | } 223 | 224 | static gnutls_x509_crt_t *load_one_ca_file(const char *path, crypto_error **error) 225 | { 226 | gnutls_x509_crt_t *list = NULL; 227 | gnutls_x509_crt_t cert; 228 | gnutls_datum dt; 229 | size_t fsize = 0; 230 | int err; 231 | 232 | dt.data = crypto_read_file(path, &fsize, error); 233 | if (!dt.data) 234 | return NULL; 235 | 236 | dt.size = (unsigned int) fsize; 237 | if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS) { 238 | gnutls_free(dt.data); 239 | crypto_error_set(error, 1, ENOMEM, "not enough memory for certificate"); 240 | goto out; 241 | } 242 | 243 | err = gnutls_x509_crt_import (cert, &dt, GNUTLS_X509_FMT_PEM); 244 | if (err != GNUTLS_E_SUCCESS) 245 | err = gnutls_x509_crt_import (cert, &dt, GNUTLS_X509_FMT_DER); 246 | gnutls_free(dt.data); 247 | if (err != GNUTLS_E_SUCCESS) { 248 | crypto_error_set(error, 1, 0, "certificate (%s) format unknown", path); 249 | goto out; 250 | } 251 | 252 | list = gnutls_malloc(sizeof(gnutls_x509_crt_t)); 253 | if (!list) { 254 | crypto_error_set(error, 1, ENOMEM, "not enough memory for certificate list"); 255 | goto out; 256 | } else 257 | list[0] = cert; 258 | 259 | out: 260 | gnutls_x509_crt_deinit (cert); 261 | return list; 262 | } 263 | 264 | static gnutls_x509_crt_t *load_ca_list_file(const char *path, 265 | size_t *out_list_size, 266 | crypto_error **error) 267 | { 268 | gnutls_x509_crt_t *list; 269 | gnutls_datum dt = { NULL, 0 }; 270 | size_t fsize = 0; 271 | int err; 272 | unsigned int num = 200; 273 | 274 | dt.data = crypto_read_file(path, &fsize, error); 275 | if (!dt.data) 276 | return NULL; 277 | 278 | dt.size = (unsigned int) fsize; 279 | list = gnutls_malloc(sizeof(gnutls_x509_crt_t) * num); 280 | if (!list) { 281 | crypto_error_set(error, 1, ENOMEM, "not enough memory for CA list"); 282 | goto out; 283 | } 284 | 285 | err = gnutls_x509_crt_list_import(list, &num, &dt, GNUTLS_X509_FMT_PEM, 0); 286 | if (err <= 0) { 287 | /* DER then maybe */ 288 | gnutls_free(list); 289 | list = load_one_ca_file(path, error); 290 | if (!list) 291 | goto out; 292 | num = 1; 293 | } else 294 | num = err; /* gnutls_x509_crt_list_import() returns # read */ 295 | 296 | if (err < 0) { 297 | crypto_error_set(error, 1, 0, "importing CA list (%d)", err); 298 | gnutls_free(list); 299 | list = NULL; 300 | } else 301 | *out_list_size = num; 302 | 303 | out: 304 | gnutls_free(dt.data); 305 | return list; 306 | } 307 | 308 | int crypto_verify_chain(crypto_ctx *ctx, 309 | const char *ca_file, 310 | const char *ca_dir, 311 | crypto_error **error) 312 | { 313 | int err, i, ret = 1, start = 0; 314 | gnutls_x509_crt_t *ca_list = NULL; 315 | size_t ca_list_size = 0; 316 | 317 | if (!ctx) 318 | return 1; 319 | 320 | if (ctx->num == 0) 321 | return 0; 322 | 323 | if (ca_file) { 324 | ca_list = load_ca_list_file(ca_file, &ca_list_size, error); 325 | if (!ca_list) 326 | return 1; 327 | } else if (ca_dir) { 328 | /* FIXME: Try to load all files in the directory I guess... */ 329 | crypto_error_set(error, 1, 0, "ca_dir not yet supported"); 330 | return 1; 331 | } 332 | 333 | /* If the server cert is self-signed, ignore it in the issuers check */ 334 | err = gnutls_x509_crt_check_issuer(ctx->stack[0], ctx->stack[0]); 335 | if (err > 0) 336 | start++; 337 | 338 | /* Check each certificate against its issuer */ 339 | for (i = start; i < ctx->num - 1; i++) { 340 | if (verify_issuer(ctx->stack[i], ctx->stack[i + 1], error)) 341 | goto out; 342 | } 343 | 344 | /* Verify the last certificate */ 345 | if (verify_last(ctx->stack[ctx->num - 1], ca_list, ca_list_size, error)) 346 | goto out; 347 | 348 | ret = 0; 349 | 350 | out: 351 | if (ca_list) { 352 | for (i = 0; i < (int) ca_list_size; i++) 353 | gnutls_x509_crt_deinit(ca_list[i]); 354 | gnutls_free(ca_list); 355 | } 356 | return ret; 357 | } 358 | 359 | static unsigned char *check_pkcs1_padding(unsigned char* from, 360 | size_t from_len, 361 | size_t *out_len, 362 | crypto_error **error) 363 | { 364 | int i = 0; 365 | unsigned char *rec_hash = NULL; 366 | size_t hash_len = 0; 367 | 368 | /* No function provided to check that hash conforms to 369 | * PKCS#1 1.5 padding scheme. Moreover gcrypt trim first 370 | * 0 bytes */ 371 | if (from[i++] != 0x01) { 372 | crypto_error_set(error, 1, 0, "hash doesn't conform to PKCS#1 padding"); 373 | goto out; 374 | } 375 | 376 | while (from[i] != 0x00) { 377 | if (from[i++] != 0xFF) { 378 | crypto_error_set(error, 1, 0, "hash doesn't conform to PKCS#1 padding"); 379 | goto out; 380 | } 381 | } 382 | 383 | i++; /* Skips 00 byte */ 384 | 385 | if (i < 10) { 386 | crypto_error_set(error, 1, 0, "PKCS#1 padding too short"); 387 | goto out; 388 | } 389 | 390 | hash_len = from_len - i; 391 | rec_hash = calloc(1, hash_len); 392 | if (!rec_hash) 393 | goto out; 394 | 395 | memcpy(rec_hash, from + i, hash_len); 396 | *out_len = hash_len; 397 | 398 | out: 399 | return rec_hash; 400 | } 401 | 402 | 403 | unsigned char *crypto_decrypt_signature(crypto_ctx *ctx, 404 | const unsigned char *sig_data, 405 | size_t sig_len, 406 | size_t *out_len, 407 | unsigned int padding, 408 | crypto_error **error) 409 | { 410 | unsigned char *buf = NULL, *rec_hash = NULL; 411 | gnutls_datum_t n = { NULL, 0 }, e = { NULL, 0 }; 412 | int err, algo; 413 | gcry_sexp_t key = NULL, sig = NULL, decrypted = NULL, child = NULL; 414 | gcry_mpi_t n_mpi = NULL, e_mpi = NULL, sig_mpi = NULL, dec_mpi = NULL; 415 | size_t buf_len = 0, hash_len = 0; 416 | 417 | if (!ctx) { 418 | crypto_error_set(error, 1, 0, "invalid crypto context"); 419 | return NULL; 420 | } 421 | 422 | if (!ctx->num) { 423 | crypto_error_set(error, 1, 0, "no certificates in the stack"); 424 | return NULL; 425 | } 426 | 427 | algo = gnutls_x509_crt_get_pk_algorithm(ctx->stack[ctx->num - 1], NULL); 428 | if (algo != GNUTLS_PK_RSA) { 429 | crypto_error_set(error, 1, 0, "certificate public key algorithm not RSA"); 430 | return NULL; 431 | } 432 | 433 | err = gnutls_x509_crt_get_pk_rsa_raw(ctx->stack[ctx->num - 1], &n, &e); 434 | if (err != GNUTLS_E_SUCCESS) { 435 | crypto_error_set(error, 1, 0, "error getting certificate public key"); 436 | return NULL; 437 | } 438 | 439 | err = gcry_mpi_scan(&n_mpi, GCRYMPI_FMT_USG, n.data, n.size, NULL); 440 | if (err) { 441 | crypto_error_set(error, 1, 0, "invalid RSA key 'n' format"); 442 | goto out; 443 | } 444 | 445 | err = gcry_mpi_scan(&e_mpi, GCRYMPI_FMT_USG, e.data, e.size, NULL); 446 | if (err) { 447 | crypto_error_set(error, 1, 0, "invalid RSA key 'e' format"); 448 | goto out; 449 | } 450 | 451 | err = gcry_sexp_build(&key, NULL, "(public-key (rsa (n %m) (e %m)))", n_mpi, e_mpi); 452 | if (err) { 453 | crypto_error_set(error, 1, 0, "could not create public-key expression"); 454 | goto out; 455 | } 456 | 457 | err = gcry_mpi_scan(&sig_mpi, GCRYMPI_FMT_USG, sig_data, sig_len, NULL); 458 | if (err) { 459 | crypto_error_set(error, 1, 0, "invalid signature format"); 460 | goto out; 461 | } 462 | 463 | err = gcry_sexp_build(&sig, NULL, "(data (flags raw) (value %m))", sig_mpi); 464 | if (err) { 465 | crypto_error_set(error, 1, 0, "could not create signature expression"); 466 | goto out; 467 | } 468 | 469 | /* encrypt is equivalent to public key decryption for RSA keys */ 470 | err = gcry_pk_encrypt(&decrypted, sig, key); 471 | if (err) { 472 | crypto_error_set(error, 1, 0, "could not decrypt signature"); 473 | goto out; 474 | } 475 | 476 | child = gcry_sexp_find_token(decrypted, "a", 1); 477 | if (!child) { 478 | crypto_error_set(error, 1, 0, "could not get decrypted signature result"); 479 | goto out; 480 | } 481 | 482 | dec_mpi = gcry_sexp_nth_mpi(child, 1, GCRYMPI_FMT_USG); 483 | gcry_sexp_release(child); 484 | 485 | if (!dec_mpi) { 486 | crypto_error_set(error, 1, 0, "could not get decrypted signature result"); 487 | goto out; 488 | } 489 | 490 | gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &buf_len, dec_mpi); 491 | if (!buf) { 492 | crypto_error_set(error, 1, 0, "could not get extract decrypted signature"); 493 | goto out; 494 | } 495 | 496 | switch (padding) { 497 | case CRYPTO_PAD_NONE: 498 | rec_hash = buf; 499 | hash_len = buf_len; 500 | buf = NULL; 501 | *out_len = (int) hash_len; 502 | break; 503 | case CRYPTO_PAD_PKCS1: 504 | rec_hash = check_pkcs1_padding(buf, buf_len, &hash_len, error); 505 | if (!rec_hash) { 506 | crypto_error_set(error, 1, 0, "could not get extract decrypted padded signature"); 507 | goto out; 508 | } 509 | *out_len = (int) hash_len; 510 | break; 511 | default: 512 | crypto_error_set(error, 1, 0, "unknown padding mechanism %d", padding); 513 | break; 514 | } 515 | 516 | out: 517 | if (buf) 518 | free(buf); 519 | if (dec_mpi) 520 | gcry_mpi_release(dec_mpi); 521 | if (decrypted) 522 | gcry_sexp_release(decrypted); 523 | if (key) 524 | gcry_sexp_release(key); 525 | if (sig) 526 | gcry_sexp_release(sig); 527 | if (sig_mpi) 528 | gcry_mpi_release(sig_mpi); 529 | if (n_mpi) 530 | gcry_mpi_release(n_mpi); 531 | if (e_mpi) 532 | gcry_mpi_release(e_mpi); 533 | if (n.data) 534 | gcry_free(n.data); 535 | if (e.data) 536 | gcry_free(e.data); 537 | 538 | return rec_hash; 539 | } 540 | 541 | -------------------------------------------------------------------------------- /test/ca_list.pem: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 5 | 8f:b0:fb:e5:0b:46:cc:4f 6 | Signature Algorithm: sha1WithRSAEncryption 7 | Issuer: OU=Root Certification Authority, CN=ca1.pem 8 | Validity 9 | Not Before: Dec 4 13:26:12 2013 GMT 10 | Not After : Jun 2 13:26:12 2033 GMT 11 | Subject: OU=Root Certification Authority, CN=ca1.pem 12 | Subject Public Key Info: 13 | Public Key Algorithm: rsaEncryption 14 | Public-Key: (4096 bit) 15 | Modulus: 16 | 00:d0:24:08:5e:8c:24:9f:df:fd:8f:f9:84:c0:d9: 17 | 88:4c:94:6f:e0:78:64:6d:b8:c6:4a:71:15:1d:ad: 18 | 8a:34:1d:64:03:f3:8f:cb:fb:2b:b9:bf:15:3a:18: 19 | 32:71:0b:89:29:3a:6a:65:29:43:d2:b7:ed:0b:02: 20 | 6f:7e:94:10:67:3e:38:f3:2f:d6:ad:94:e1:04:45: 21 | 80:1a:89:3d:20:3b:45:b7:ee:f5:b5:39:f3:1d:3a: 22 | 72:e0:ab:86:99:46:0f:0f:50:90:e2:28:b8:9d:1a: 23 | 61:84:ed:ca:fb:9f:15:e5:a1:2a:2f:01:de:c6:a6: 24 | 4a:4e:3a:5a:b8:a4:cf:8f:90:60:b7:b1:7d:ea:01: 25 | ad:d9:0d:01:64:92:a1:3f:b0:24:eb:ac:6e:ff:fb: 26 | 2c:65:fd:dd:bc:4a:95:ba:37:a0:ed:ed:13:e6:49: 27 | a8:4a:4e:6c:a0:92:40:d8:74:5f:3f:32:79:27:9e: 28 | 28:a0:0c:53:53:23:18:db:82:16:b8:72:89:8a:08: 29 | 2c:e0:67:71:d4:5d:32:bc:97:89:c5:14:55:2d:b5: 30 | ce:e4:28:94:21:38:f9:42:0e:e7:bc:45:8d:43:54: 31 | 28:93:75:de:2d:de:83:e2:f5:8a:f1:f7:80:e6:ad: 32 | 16:84:fd:2e:59:47:96:71:e9:49:08:72:77:d7:32: 33 | 08:2b:a9:a0:7e:bc:5d:a6:b6:2e:44:5e:9d:67:cd: 34 | c1:ec:0c:44:ec:47:2d:c3:f4:d2:8e:08:05:03:77: 35 | 72:0b:a2:b6:f4:da:32:f3:84:54:ad:46:85:82:9a: 36 | 08:79:4e:97:35:2d:14:35:22:35:51:6e:c8:73:8c: 37 | 9a:25:90:ef:c1:cf:8b:40:a6:5e:a4:23:d0:28:19: 38 | 4e:56:b4:8b:39:74:e8:5a:57:ca:28:0a:bb:aa:e3: 39 | 54:3a:18:2f:31:b9:41:53:3e:bf:a4:f0:8b:3b:85: 40 | bb:c0:7d:fd:5a:08:b9:d8:84:51:c7:23:27:44:82: 41 | c1:af:e4:f2:db:99:46:a1:7f:35:03:f4:1a:a1:3a: 42 | b9:55:a0:bf:6b:c9:7f:9f:66:ac:10:c4:99:12:8f: 43 | 72:b8:3d:39:85:bf:9f:e1:ea:e2:42:c6:e1:e7:58: 44 | 07:1e:0c:c7:43:1a:47:54:a6:77:59:59:20:15:98: 45 | e7:30:4e:94:23:ef:c2:96:bd:ca:ab:ea:03:b1:cf: 46 | 76:46:1f:d1:45:85:94:a0:f2:74:d4:50:8e:23:24: 47 | ca:79:fc:8c:a8:36:61:1c:40:67:fa:b2:f5:59:e9: 48 | fa:f2:73:11:52:0e:3c:db:42:21:76:9a:48:24:2e: 49 | f2:64:84:52:c2:57:6b:4d:2a:1c:15:8c:00:cf:94: 50 | 9e:b0:c3 51 | Exponent: 65537 (0x10001) 52 | X509v3 extensions: 53 | X509v3 Subject Key Identifier: 54 | 99:77:DD:22:D3:28:B4:E6:7D:40:1D:ED:DB:7F:BD:3C:00:D3:88:28 55 | X509v3 Authority Key Identifier: 56 | keyid:99:77:DD:22:D3:28:B4:E6:7D:40:1D:ED:DB:7F:BD:3C:00:D3:88:28 57 | 58 | X509v3 Basic Constraints: 59 | CA:TRUE 60 | Signature Algorithm: sha1WithRSAEncryption 61 | 7b:32:1c:c2:21:13:f6:c2:0c:30:e4:59:66:28:2f:69:de:50: 62 | c2:e2:c9:f3:b6:36:2f:a4:a9:34:1a:9f:e4:4c:e5:a1:f0:be: 63 | a7:e0:a4:f7:e2:a2:36:01:9a:68:4b:1f:a7:90:48:a9:c4:35: 64 | d6:47:86:d3:f0:f4:2c:55:f2:2b:39:61:ef:82:32:ea:aa:82: 65 | ec:20:7d:37:2f:ba:b4:a7:a6:86:92:72:dc:bc:27:73:d4:c3: 66 | f0:bc:2f:16:0d:69:63:5e:f8:78:5c:b7:98:bb:b4:4d:cc:47: 67 | f8:36:57:86:5c:bb:55:1b:7b:cd:32:8f:e7:bc:e0:fc:32:5a: 68 | ed:5c:c5:5b:1f:c0:c3:9a:54:8a:92:eb:97:c0:9f:24:f2:7f: 69 | df:e5:a5:f5:50:98:6c:65:31:40:df:4f:f1:47:f8:86:6f:4c: 70 | a1:6a:ef:ab:2a:1f:f1:79:04:fd:2d:80:ca:b3:f3:98:f2:7d: 71 | 2b:1a:43:3c:ad:30:59:bb:ea:34:5e:29:e3:76:4d:35:ff:0c: 72 | c1:73:5c:cb:9f:48:72:87:f0:d6:96:c1:6c:a1:d7:9a:92:b4: 73 | 46:2f:f0:ef:61:8b:02:93:ef:40:40:33:29:8c:c7:20:77:ca: 74 | 7f:8a:25:3e:10:0a:e0:23:c9:b5:6d:6b:15:89:56:2a:f2:d2: 75 | 75:52:15:80:4c:04:35:42:ac:bc:a0:1f:48:e4:cc:d8:62:88: 76 | 5e:5c:a2:aa:9e:d4:63:77:46:d5:51:5d:00:2c:fc:99:e2:c3: 77 | 31:a6:19:22:db:66:8c:37:35:c4:7d:5f:fc:ee:0f:a2:d3:cd: 78 | 2d:90:49:af:35:4a:47:96:6b:3e:91:6c:56:4b:29:39:01:f2: 79 | 17:1d:30:bb:74:0b:9d:8d:54:c3:37:1e:32:cb:b8:99:85:88: 80 | 00:be:e2:21:85:fc:42:d2:ab:bf:34:99:96:46:7f:28:6e:4c: 81 | c9:dc:f3:9d:37:9c:f6:1e:7e:bb:9e:9a:66:02:df:3f:68:1f: 82 | 5b:a3:38:dd:fe:c6:93:7b:1f:98:76:54:79:c1:8a:0b:ea:91: 83 | 00:e5:7c:9d:94:93:f1:e4:44:70:3f:81:8f:12:32:13:10:2a: 84 | 5f:81:b4:e7:40:ea:16:e9:23:f8:b7:f4:c9:70:24:08:4a:45: 85 | 50:36:48:e1:1a:25:fa:af:f3:17:26:34:43:22:aa:7c:86:45: 86 | f8:b7:36:5a:44:16:51:98:84:df:e2:50:33:b5:ff:42:61:8d: 87 | e5:ca:44:b0:06:12:ad:01:90:c6:fe:90:25:db:ab:42:b8:2a: 88 | d1:c8:f2:5f:ad:a0:21:df:a3:99:96:d4:1d:87:1e:45:42:a1: 89 | 85:5f:81:19:a5:db:5c:3e 90 | -----BEGIN CERTIFICATE----- 91 | MIIFRTCCAy2gAwIBAgIJAI+w++ULRsxPMA0GCSqGSIb3DQEBBQUAMDkxJTAjBgNV 92 | BAsMHFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB2NhMS5w 93 | ZW0wHhcNMTMxMjA0MTMyNjEyWhcNMzMwNjAyMTMyNjEyWjA5MSUwIwYDVQQLDBxS 94 | b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRAwDgYDVQQDDAdjYTEucGVtMIIC 95 | IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0CQIXowkn9/9j/mEwNmITJRv 96 | 4HhkbbjGSnEVHa2KNB1kA/OPy/srub8VOhgycQuJKTpqZSlD0rftCwJvfpQQZz44 97 | 8y/WrZThBEWAGok9IDtFt+71tTnzHTpy4KuGmUYPD1CQ4ii4nRphhO3K+58V5aEq 98 | LwHexqZKTjpauKTPj5Bgt7F96gGt2Q0BZJKhP7Ak66xu//ssZf3dvEqVujeg7e0T 99 | 5kmoSk5soJJA2HRfPzJ5J54ooAxTUyMY24IWuHKJiggs4Gdx1F0yvJeJxRRVLbXO 100 | 5CiUITj5Qg7nvEWNQ1Qok3XeLd6D4vWK8feA5q0WhP0uWUeWcelJCHJ31zIIK6mg 101 | frxdprYuRF6dZ83B7AxE7Ectw/TSjggFA3dyC6K29Noy84RUrUaFgpoIeU6XNS0U 102 | NSI1UW7Ic4yaJZDvwc+LQKZepCPQKBlOVrSLOXToWlfKKAq7quNUOhgvMblBUz6/ 103 | pPCLO4W7wH39Wgi52IRRxyMnRILBr+Ty25lGoX81A/QaoTq5VaC/a8l/n2asEMSZ 104 | Eo9yuD05hb+f4eriQsbh51gHHgzHQxpHVKZ3WVkgFZjnME6UI+/Clr3Kq+oDsc92 105 | Rh/RRYWUoPJ01FCOIyTKefyMqDZhHEBn+rL1Wen68nMRUg4820IhdppIJC7yZIRS 106 | wldrTSocFYwAz5SesMMCAwEAAaNQME4wHQYDVR0OBBYEFJl33SLTKLTmfUAd7dt/ 107 | vTwA04goMB8GA1UdIwQYMBaAFJl33SLTKLTmfUAd7dt/vTwA04goMAwGA1UdEwQF 108 | MAMBAf8wDQYJKoZIhvcNAQEFBQADggIBAHsyHMIhE/bCDDDkWWYoL2neUMLiyfO2 109 | Ni+kqTQan+RM5aHwvqfgpPfiojYBmmhLH6eQSKnENdZHhtPw9CxV8is5Ye+CMuqq 110 | guwgfTcvurSnpoaScty8J3PUw/C8LxYNaWNe+Hhct5i7tE3MR/g2V4Zcu1Ube80y 111 | j+e84PwyWu1cxVsfwMOaVIqS65fAnyTyf9/lpfVQmGxlMUDfT/FH+IZvTKFq76sq 112 | H/F5BP0tgMqz85jyfSsaQzytMFm76jReKeN2TTX/DMFzXMufSHKH8NaWwWyh15qS 113 | tEYv8O9hiwKT70BAMymMxyB3yn+KJT4QCuAjybVtaxWJViry0nVSFYBMBDVCrLyg 114 | H0jkzNhiiF5coqqe1GN3RtVRXQAs/JniwzGmGSLbZow3NcR9X/zuD6LTzS2QSa81 115 | SkeWaz6RbFZLKTkB8hcdMLt0C52NVMM3HjLLuJmFiAC+4iGF/ELSq780mZZGfyhu 116 | TMnc8503nPYefruemmYC3z9oH1ujON3+xpN7H5h2VHnBigvqkQDlfJ2Uk/HkRHA/ 117 | gY8SMhMQKl+BtOdA6hbpI/i39MlwJAhKRVA2SOEaJfqv8xcmNEMiqnyGRfi3NlpE 118 | FlGYhN/iUDO1/0JhjeXKRLAGEq0BkMb+kCXbq0K4KtHI8l+toCHfo5mW1B2HHkVC 119 | oYVfgRml21w+ 120 | -----END CERTIFICATE----- 121 | Certificate: 122 | Data: 123 | Version: 3 (0x2) 124 | Serial Number: 125 | b6:36:ad:93:f7:5f:26:91 126 | Signature Algorithm: sha1WithRSAEncryption 127 | Issuer: OU=Root Certification Authority, CN=ca2.pem 128 | Validity 129 | Not Before: Dec 4 13:26:13 2013 GMT 130 | Not After : Jun 2 13:26:13 2033 GMT 131 | Subject: OU=Root Certification Authority, CN=ca2.pem 132 | Subject Public Key Info: 133 | Public Key Algorithm: rsaEncryption 134 | Public-Key: (2048 bit) 135 | Modulus: 136 | 00:ea:19:0b:81:0f:b8:f1:1b:8c:a3:d6:ca:43:06: 137 | 2d:b5:d3:45:95:cd:cb:cc:da:f4:4b:d0:da:77:2a: 138 | 60:53:47:61:aa:79:99:f8:24:5c:5f:e6:57:72:c8: 139 | 22:6d:3c:6f:a8:45:a3:5f:f9:c3:0d:76:bf:6c:a7: 140 | f9:25:be:d2:a2:08:cb:8b:4e:00:41:e8:40:88:86: 141 | a2:63:a3:c1:35:f8:82:ea:7e:53:8c:c9:3f:95:33: 142 | d6:24:51:22:e8:b9:b1:1b:43:67:49:aa:57:4a:d5: 143 | ad:0c:11:bf:c9:58:d7:24:97:51:34:9a:30:9a:d1: 144 | f0:ec:2d:7b:1c:ef:fd:af:05:e4:69:09:81:86:8d: 145 | 8e:dc:33:8d:1f:4d:20:de:d1:8d:5e:d7:de:fc:e3: 146 | 7e:b2:0a:0b:31:23:ff:de:ff:61:44:3f:72:ec:48: 147 | ca:01:94:2e:8e:3f:cf:fe:af:b3:19:da:e8:15:39: 148 | 66:15:db:a4:5a:c0:38:8e:2d:94:31:96:a7:08:fc: 149 | aa:03:2e:e2:ab:f9:53:fc:8a:42:ef:2c:d9:1d:cd: 150 | 81:b9:9a:fc:3e:08:c3:63:64:57:dd:18:9e:61:52: 151 | ab:43:fc:af:7a:3d:8d:99:52:73:0d:86:a7:d7:01: 152 | 34:2d:cd:e6:c4:cc:99:01:dd:c7:cf:b1:64:8f:2c: 153 | d5:73 154 | Exponent: 65537 (0x10001) 155 | X509v3 extensions: 156 | X509v3 Subject Key Identifier: 157 | 68:C1:E8:F8:2B:27:CC:15:73:17:5E:E9:96:58:B0:1E:D8:9C:8D:9E 158 | X509v3 Authority Key Identifier: 159 | keyid:68:C1:E8:F8:2B:27:CC:15:73:17:5E:E9:96:58:B0:1E:D8:9C:8D:9E 160 | 161 | X509v3 Basic Constraints: 162 | CA:TRUE 163 | Signature Algorithm: sha1WithRSAEncryption 164 | 41:39:9e:d2:fb:82:4f:bc:92:56:d7:de:43:e4:94:72:60:a2: 165 | 0e:0c:50:9a:8a:fe:f2:74:63:36:4c:a8:1c:49:bc:aa:82:ae: 166 | 39:ff:69:67:46:04:f9:17:b2:da:b1:cd:14:f6:7e:0a:e7:87: 167 | 2d:87:98:59:81:91:93:e6:61:f4:56:6e:7d:22:79:3d:a4:73: 168 | d5:00:a2:1a:8f:5c:cb:e6:53:04:55:a3:cc:5b:de:da:8e:63: 169 | 49:72:d8:10:fd:be:dc:e3:50:83:06:4c:da:96:d3:37:dd:3e: 170 | f5:41:08:0b:63:3d:47:08:c1:0b:be:4c:87:28:44:9f:72:fd: 171 | 2a:aa:44:2b:cd:a5:a3:11:1e:01:e0:f5:c8:df:88:ed:8c:07: 172 | fa:99:dd:dd:2a:67:80:70:81:d3:1d:13:40:de:a1:25:e1:f3: 173 | 05:7d:97:b1:c4:d6:17:01:1c:57:a9:70:4c:22:31:45:6a:9e: 174 | 4c:d4:14:41:8a:22:d6:a5:49:6b:4b:8a:4d:80:80:ab:1d:b4: 175 | 8f:71:6f:78:c8:a2:52:cf:36:7c:f3:0f:f7:7d:19:22:31:ec: 176 | 88:f2:16:61:ff:a0:6b:4c:39:57:1d:a2:ce:5a:9e:dd:a7:4b: 177 | 31:52:80:9b:ca:fa:83:43:92:91:03:2a:d1:74:b7:b6:08:9b: 178 | fa:88:ef:e1 179 | -----BEGIN CERTIFICATE----- 180 | MIIDRTCCAi2gAwIBAgIJALY2rZP3XyaRMA0GCSqGSIb3DQEBBQUAMDkxJTAjBgNV 181 | BAsMHFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB2NhMi5w 182 | ZW0wHhcNMTMxMjA0MTMyNjEzWhcNMzMwNjAyMTMyNjEzWjA5MSUwIwYDVQQLDBxS 183 | b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRAwDgYDVQQDDAdjYTIucGVtMIIB 184 | IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6hkLgQ+48RuMo9bKQwYttdNF 185 | lc3LzNr0S9DadypgU0dhqnmZ+CRcX+ZXcsgibTxvqEWjX/nDDXa/bKf5Jb7SogjL 186 | i04AQehAiIaiY6PBNfiC6n5TjMk/lTPWJFEi6LmxG0NnSapXStWtDBG/yVjXJJdR 187 | NJowmtHw7C17HO/9rwXkaQmBho2O3DONH00g3tGNXtfe/ON+sgoLMSP/3v9hRD9y 188 | 7EjKAZQujj/P/q+zGdroFTlmFdukWsA4ji2UMZanCPyqAy7iq/lT/IpC7yzZHc2B 189 | uZr8PgjDY2RX3RieYVKrQ/yvej2NmVJzDYan1wE0Lc3mxMyZAd3Hz7FkjyzVcwID 190 | AQABo1AwTjAdBgNVHQ4EFgQUaMHo+CsnzBVzF17plliwHticjZ4wHwYDVR0jBBgw 191 | FoAUaMHo+CsnzBVzF17plliwHticjZ4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B 192 | AQUFAAOCAQEAQTme0vuCT7ySVtfeQ+SUcmCiDgxQmor+8nRjNkyoHEm8qoKuOf9p 193 | Z0YE+Rey2rHNFPZ+CueHLYeYWYGRk+Zh9FZufSJ5PaRz1QCiGo9cy+ZTBFWjzFve 194 | 2o5jSXLYEP2+3ONQgwZM2pbTN90+9UEIC2M9RwjBC75MhyhEn3L9KqpEK82loxEe 195 | AeD1yN+I7YwH+pnd3SpngHCB0x0TQN6hJeHzBX2XscTWFwEcV6lwTCIxRWqeTNQU 196 | QYoi1qVJa0uKTYCAqx20j3FveMiiUs82fPMP930ZIjHsiPIWYf+ga0w5Vx2izlqe 197 | 3adLMVKAm8r6g0OSkQMq0XS3tgib+ojv4Q== 198 | -----END CERTIFICATE----- 199 | Certificate: 200 | Data: 201 | Version: 3 (0x2) 202 | Serial Number: 203 | 9f:ab:17:25:a8:44:2d:cd 204 | Signature Algorithm: sha1WithRSAEncryption 205 | Issuer: OU=Root Certification Authority, CN=ca3.pem 206 | Validity 207 | Not Before: Dec 4 13:26:13 2013 GMT 208 | Not After : Jun 2 13:26:13 2033 GMT 209 | Subject: OU=Root Certification Authority, CN=ca3.pem 210 | Subject Public Key Info: 211 | Public Key Algorithm: rsaEncryption 212 | Public-Key: (2048 bit) 213 | Modulus: 214 | 00:bd:8b:3c:b6:0a:8e:17:f0:49:0e:36:c7:41:09: 215 | 9a:ab:b4:47:f5:66:38:ae:92:45:b9:2a:53:1e:a6: 216 | ea:01:db:2b:be:fc:cf:1b:82:a6:a0:df:ef:96:4b: 217 | f4:44:3a:97:37:fd:0f:93:22:ee:94:97:d1:17:50: 218 | 09:07:07:2a:6e:2d:ea:fb:21:cf:24:85:db:c1:93: 219 | 95:fc:95:3d:13:4e:42:6e:56:20:57:2c:a2:e6:b1: 220 | e4:41:eb:0c:14:b1:39:d5:8a:69:a0:df:26:af:15: 221 | cf:13:3d:81:18:38:32:9a:40:ad:9d:82:6f:43:38: 222 | 35:5b:44:55:fc:20:bd:30:3b:65:bb:eb:1c:52:6f: 223 | 1b:a9:04:19:15:47:f3:03:9d:b6:f6:a6:f9:da:0c: 224 | 5f:41:36:e6:47:f7:d2:15:25:3c:07:fc:7e:88:08: 225 | f3:b8:17:e8:f2:7b:8e:e5:ba:27:d0:43:9a:a5:01: 226 | 13:3b:bf:37:44:d6:65:ce:81:fb:a6:35:b4:d7:4d: 227 | 6d:31:11:de:20:0b:2d:49:fc:60:9b:37:bf:03:5b: 228 | c2:46:00:63:5d:64:80:48:b4:f5:49:dc:97:a9:7e: 229 | 6e:c7:33:74:71:1e:8a:7d:d4:d5:e0:d2:a5:9c:f0: 230 | 30:0a:1a:63:59:d3:f5:ce:93:e2:60:86:38:94:13: 231 | 35:05 232 | Exponent: 65537 (0x10001) 233 | X509v3 extensions: 234 | X509v3 Subject Key Identifier: 235 | E5:0F:44:4E:46:BE:03:BE:BF:7E:3F:83:26:17:94:39:9A:38:34:55 236 | X509v3 Authority Key Identifier: 237 | keyid:E5:0F:44:4E:46:BE:03:BE:BF:7E:3F:83:26:17:94:39:9A:38:34:55 238 | 239 | X509v3 Basic Constraints: 240 | CA:TRUE 241 | Signature Algorithm: sha1WithRSAEncryption 242 | 82:3a:9b:f8:01:23:35:18:9e:ee:f0:0e:45:f9:45:de:cc:42: 243 | 69:f6:9d:9f:c6:6f:e3:78:21:94:1c:aa:23:9d:3c:11:fd:83: 244 | 92:2b:4d:c6:0b:3f:e5:f1:da:2e:ab:a4:30:56:ae:5d:90:62: 245 | ee:5e:ee:c3:27:2b:3e:9e:4f:57:69:65:50:52:60:41:07:8f: 246 | b2:15:ec:27:14:58:c6:9f:4f:f1:b2:86:09:15:f3:b6:53:36: 247 | 34:4c:c2:c5:50:b3:57:25:d0:44:0d:d6:2f:42:cc:54:b6:c8: 248 | e7:53:24:b7:b9:d4:63:ba:0a:a3:db:1e:16:40:4c:bb:1d:c4: 249 | 06:01:8d:b1:9a:7b:21:df:6d:c4:f3:e3:12:30:56:d9:43:3b: 250 | 43:1a:da:8e:8c:56:38:92:e9:d5:9d:3c:51:58:ed:e0:2b:f2: 251 | 29:7f:1c:0c:f0:df:a5:da:14:70:3b:85:a5:39:14:bf:a2:13: 252 | 05:25:95:0d:8d:3b:28:e9:5c:26:5c:14:e8:56:da:c4:a7:f9: 253 | 93:3a:c1:60:41:2b:bf:81:2a:fe:e2:75:ec:cf:8d:77:1b:6e: 254 | b8:b2:50:84:d1:ce:67:86:7f:06:6e:5d:7e:29:92:a0:d8:c4: 255 | 6c:bb:79:3d:8f:59:dd:d4:02:05:8a:93:ef:5c:7b:8f:38:7b: 256 | 0e:b9:3a:f3 257 | -----BEGIN CERTIFICATE----- 258 | MIIDRTCCAi2gAwIBAgIJAJ+rFyWoRC3NMA0GCSqGSIb3DQEBBQUAMDkxJTAjBgNV 259 | BAsMHFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB2NhMy5w 260 | ZW0wHhcNMTMxMjA0MTMyNjEzWhcNMzMwNjAyMTMyNjEzWjA5MSUwIwYDVQQLDBxS 261 | b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRAwDgYDVQQDDAdjYTMucGVtMIIB 262 | IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvYs8tgqOF/BJDjbHQQmaq7RH 263 | 9WY4rpJFuSpTHqbqAdsrvvzPG4KmoN/vlkv0RDqXN/0PkyLulJfRF1AJBwcqbi3q 264 | +yHPJIXbwZOV/JU9E05CblYgVyyi5rHkQesMFLE51YppoN8mrxXPEz2BGDgymkCt 265 | nYJvQzg1W0RV/CC9MDtlu+scUm8bqQQZFUfzA5229qb52gxfQTbmR/fSFSU8B/x+ 266 | iAjzuBfo8nuO5bon0EOapQETO783RNZlzoH7pjW0101tMRHeIAstSfxgmze/A1vC 267 | RgBjXWSASLT1SdyXqX5uxzN0cR6KfdTV4NKlnPAwChpjWdP1zpPiYIY4lBM1BQID 268 | AQABo1AwTjAdBgNVHQ4EFgQU5Q9ETka+A76/fj+DJheUOZo4NFUwHwYDVR0jBBgw 269 | FoAU5Q9ETka+A76/fj+DJheUOZo4NFUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B 270 | AQUFAAOCAQEAgjqb+AEjNRie7vAORflF3sxCafadn8Zv43ghlByqI508Ef2DkitN 271 | xgs/5fHaLqukMFauXZBi7l7uwycrPp5PV2llUFJgQQePshXsJxRYxp9P8bKGCRXz 272 | tlM2NEzCxVCzVyXQRA3WL0LMVLbI51Mkt7nUY7oKo9seFkBMux3EBgGNsZp7Id9t 273 | xPPjEjBW2UM7QxrajoxWOJLp1Z08UVjt4CvyKX8cDPDfpdoUcDuFpTkUv6ITBSWV 274 | DY07KOlcJlwU6FbaxKf5kzrBYEErv4Eq/uJ17M+NdxtuuLJQhNHOZ4Z/Bm5dfimS 275 | oNjEbLt5PY9Z3dQCBYqT71x7jzh7Drk68w== 276 | -----END CERTIFICATE----- 277 | --------------------------------------------------------------------------------