From a3f625954aa8050b9b1745472cb7fe97d0c28abf Mon Sep 17 00:00:00 2001 From: Philip Prindeville Date: Wed, 14 Apr 2021 18:16:25 -0600 Subject: [PATCH] strongswan: add certificate generation utility Signed-off-by: Philip Prindeville --- net/strongswan/Makefile | 19 +++- net/strongswan/files/gencerts.sh | 155 +++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+), 1 deletion(-) create mode 100755 net/strongswan/files/gencerts.sh diff --git a/net/strongswan/Makefile b/net/strongswan/Makefile index ff7d5cefe..3b45a2222 100644 --- a/net/strongswan/Makefile +++ b/net/strongswan/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=strongswan PKG_VERSION:=5.9.2 -PKG_RELEASE:=4 +PKG_RELEASE:=5 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=https://download.strongswan.org/ https://download2.strongswan.org/ @@ -418,6 +418,17 @@ $(call Package/strongswan/description/Default) This package contains the swanctl utility. endef +define Package/strongswan-gencerts +$(call Package/strongswan/Default) + TITLE+= X.509 certificate generation utility + DEPENDS:= strongswan +strongswan-pki bash +endef + +define Package/strongswan-gencerts/description +$(call Package/strongswan/description/Default) + This package contains the X.509 certificate generation utility. +endef + define Package/strongswan-libtls $(call Package/strongswan/Default) TITLE+= libtls @@ -576,6 +587,11 @@ define Package/strongswan-swanctl/install $(INSTALL_BIN) ./files/swanctl.init $(1)/etc/init.d/swanctl endef +define Package/strongswan-gencerts/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) ./files/gencerts.sh $(1)/usr/bin/gencerts +endef + define Package/strongswan-libtls/install $(INSTALL_DIR) $(1)/usr/lib/ipsec $(CP) $(PKG_INSTALL_DIR)/usr/lib/ipsec/libtls.so.* $(1)/usr/lib/ipsec/ @@ -651,6 +667,7 @@ $(eval $(call BuildPackage,strongswan-libnttfft)) $(eval $(call BuildPackage,strongswan-pki)) $(eval $(call BuildPackage,strongswan-scepclient)) $(eval $(call BuildPackage,strongswan-swanctl)) +$(eval $(call BuildPackage,strongswan-gencerts)) $(eval $(call BuildPackage,strongswan-libtls)) $(eval $(call BuildPlugin,addrblock,RFC 3779 address block constraint support,)) $(eval $(call BuildPlugin,aes,AES crypto,)) diff --git a/net/strongswan/files/gencerts.sh b/net/strongswan/files/gencerts.sh new file mode 100755 index 000000000..57dc0df6d --- /dev/null +++ b/net/strongswan/files/gencerts.sh @@ -0,0 +1,155 @@ +#!/bin/sh + +# +# see: +# https://www.howtoforge.com/tutorial/strongswan-based-ipsec-vpn-using-certificates-and-pre-shared-key-on-ubuntu-16-04/ +# + +PROG=$(basename "$0") + +[ -z "$EUID" ] && EUID=$(id -u) + +if [ $# -lt 5 ]; then + echo "Usage: $PROG { -s | -c | -u } country domain organization identities [ ... ]" >&2 + exit 1 +fi + +case "$1" in +-s) + S_OPT=1 ;; +-c) + C_OPT=1 ;; +-u) + U_OPT=1 ;; +*) + echo "$PROG: require an option specifying server/client/user credential type" >&2 + exit 1 + ;; +esac +shift + +C="$1"; shift +DOMAIN="$1"; shift +SHORT_DOMAIN="${DOMAIN%%.*}" +ORG="$1"; shift + +# invariants... +STRONGSWANDIR=/etc +SWANCTL_DIR=$STRONGSWANDIR/swanctl +: ${KEYINFO:="rsa:4096"} +: ${CADAYS:=3650} +: ${CRTDAYS:=730} + +makeDN() +{ + printf "C=%s, O=%s, CN=%s" "$1" "$2" "$3" +} + +field() +{ + local arg="$1" + local nth="$2" + + echo "$arg" | cut -d ':' -f "$nth" +} + +genmasterkey() +{ + local keytype keybits + + keytype=$(field "$KEYINFO" 1) + keybits=$(field "$KEYINFO" 2) + + pki --gen --type "$keytype" --size "$keybits" --outform pem > "$SWANCTL_DIR/private/$SHORT_DOMAIN.key" + chmod 0400 "$SWANCTL_DIR/private/$SHORT_DOMAIN.key" +} + +genca() +{ + local keytype + + keytype=$(field "$KEYINFO" 1) + + pki --self --ca --lifetime "$CADAYS" --in "$SWANCTL_DIR/private/$SHORT_DOMAIN.key" --type "$keytype" \ + --dn "$ROOTDN" --outform pem > "$SWANCTL_DIR/x509ca/$SHORT_DOMAIN.crt" + chmod 0444 "$SWANCTL_DIR/cacerts/$SHORT_DOMAIN.crt" +} + +genclientkey() +{ + local name="$1" keytype keybits + + keytype=$(field "$KEYINFO" 1) + keybits=$(field "$KEYINFO" 2) + + pki --gen --type "$keytype" --size "$keybits" --outform pem > "$SWANCTL_DIR/private/$name.key" + chmod 0400 "$SWANCTL_DIR/private/$name.key" +} + +gendevcert() +{ + local dn="$1" + local san="$2" + local name="$3" + + # reads key from input + pki --issue --lifetime "$CRTDAYS" \ + --cacert "$SWANCTL_DIR/x509ca/$SHORT_DOMAIN.crt" \ + --cakey "$SWANCTL_DIR/private/$SHORT_DOMAIN.key" \ + --dn "$dn" --san "$san" \ + ${S_OPT:+--flag serverAuth} \ + ${S_OPT:---flag clientAuth} \ + --flag ikeIntermediate \ + --outform pem > "$SWANCTL_DIR/x509/$name.crt" + chmod 0444 "$SWANCTL_DIR/x509/$name.crt" +} + +gendev() +{ + local keytype + + keytype=$(field "$KEYINFO" 1) + + [ -f "$SWANCTL_DIR/private/$NAME.key" ] || genclientkey "$NAME" + + [ -f "$SWANCTL_DIR/x509/$NAME.crt" ] || \ + pki --pub --in "$SWANCTL_DIR/private/$NAME.key" --type "$keytype" \ + | gendevcert "$DEVDN" "$DEVSAN" "$NAME" +} + +setparams() +{ + NAME="$1" + + if [ -n "$U_OPT" ]; then + DEVSAN="$NAME@$DOMAIN" + DEVDN="$(makeDN "$C" "$ORG" "$DEVSAN")" + else + DEVSAN="$NAME.$DOMAIN" + DEVDN="$(makeDN "$C" "$ORG" "$NAME")" + fi +} + +umask 077 + +[ "$EUID" -eq 0 ] || { echo "Must run as root!" >&2 ; exit 1; } + +ROOTDN="$(makeDN "$C" "$ORG" "Root CA")" + +[ -f "$SWANCTL_DIR/private/$SHORT_DOMAIN.key" ] || genmasterkey + +[ -f "$SWANCTL_DIR/x509ca/$SHORT_DOMAIN.crt" ] || genca + +PARENT="$STRONGSWANDIR" +BASEDIR="${SWANCTL_DIR##$PARENT/}" + +for name in "$@"; do + setparams "$name" + gendev + + tar -zcf "$name-certs.tar.gz" -C "$PARENT" "$BASEDIR/x509ca/$SHORT_DOMAIN.crt" "$BASEDIR/x509/$name.crt" "$BASEDIR/private/$name.key" + chmod 600 "$name-certs.tar.gz" + echo "Generated as $name-certs.tar.gz" +done + +exit 0