Dockerfiles for v3 ACA. Also Powershell Package Scripts (#628)

* Package scripts for powershell

* Adding dockerfiles
This commit is contained in:
5B96790E3664F40075A67E6ADF737EDB15B4408DBC91A81228B31537B0CE3E26 2023-11-09 11:54:51 -05:00 committed by GitHub
parent 6aba9b9c5d
commit 1e3c7c78b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1441 additions and 2 deletions

View File

@ -0,0 +1,75 @@
FROM rockylinux:9
LABEL org.opencontainers.image.vendor NSA Laboratory for Advanced Cybersecurity Research
LABEL org.opencontainers.image.source https://github.com/nsacyber/hirs
LABEL org.opencontainers.image.description NSA\'s HIRS Attestation Certificate Authority. Expose port 8443 to access the portal from outside the container.
SHELL ["/bin/bash", "-c"]
# Rocky 9 has a different channel for some apps
RUN dnf install -y 'dnf-command(config-manager)' && dnf config-manager --set-enabled crb
# Update and install OS-dependencies
RUN dnf update -y
# Dependencies were selected for these reasons:
# OS setup/Unknown direct impact for HIRS
ENV HIRS_DNF_OS_SETUP="initscripts firewalld policycoreutils policycoreutils-python-utils net-tools"
# OS tools
ENV HIRS_DNF_OS_TOOLS="git sudo vim wget"
# ACA compile
ENV HIRS_DNF_ACA_COMPILE="java-17-openjdk-devel"
# ACA run
ENV HIRS_DNF_ACA_RUN="mariadb-server"
# IBM TPM simulator compile
ENV HIRS_DNF_TPM_COMPILE="tpm2-tools gcc cmake openssl-devel"
# Download and install all dependencies at one time
RUN dnf -y install $(echo "$HIRS_DNF_OS_SETUP") $(echo "$HIRS_DNF_OS_TOOLS") $(echo "$HIRS_DNF_ACA_COMPILE") $(echo "$HIRS_DNF_ACA_RUN") $(echo "$HIRS_DNF_TPM_COMPILE")
# Set up TPM Simulator
RUN git clone https://github.com/kgoldman/ibmswtpm2 /ibmswtpm2
WORKDIR /ibmswtpm2/src
RUN make
# The following script allows the TPM to be set up in the docker image.
# This will install an empty TPM.
RUN echo "#!/bin/bash" > /tmp/tpm_config && \
echo "/ibmswtpm2/src/tpm_server &" >> /tmp/tpm_config && \
echo "sleep 5" >> /tmp/tpm_config && \
echo "tpm2_startup -c" >> /tmp/tpm_config && \
bash /tmp/tpm_config && \
rm -rf /tmp/tpm_config
#EXPOSE 8080 # Only needed if TLS is not working.
EXPOSE 8443
# Checkout HIRS
RUN git clone -b main https://github.com/nsacyber/HIRS.git /repo
# Defensive copy of the repo so it's easy to start fresh if needed
RUN mkdir /hirs
WORKDIR /repo
RUN cp -r . /hirs
# Run bootwar to cache build artifacts
WORKDIR /hirs
RUN ./gradlew bootWar
# Add ACA TLS certification path to container OS
# Allows the curl command in the HEALTHCHECK to work with TLS
# These commands are placed into a script that can be run after aca_setup.sh on container launch.
RUN echo "#!/bin/bash" > /tmp/hirs_add_aca_tls_path_to_os.sh && \
echo "cp /etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_intermediate_ca_rsa_3k_sha384.pem /etc/pki/ca-trust/source/anchors/" >> /tmp/hirs_add_aca_tls_path_to_os.sh && \
echo "cp /etc/hirs/certificates/HIRS/ecc_512_sha384_certs/HIRS_intermediate_ca_ecc_512_sha384.pem /etc/pki/ca-trust/source/anchors/" >> /tmp/hirs_add_aca_tls_path_to_os.sh && \
echo "cp /etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_root_ca_rsa_3k_sha384.pem /etc/pki/ca-trust/source/anchors/" >> /tmp/hirs_add_aca_tls_path_to_os.sh && \
echo "cp /etc/hirs/certificates/HIRS/ecc_512_sha384_certs/HIRS_root_ca_ecc_512_sha384.pem /etc/pki/ca-trust/source/anchors/" >> /tmp/hirs_add_aca_tls_path_to_os.sh && \
echo "cp /etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_leaf_ca3_rsa_3k_sha384.pem /etc/pki/ca-trust/source/anchors/" >> /tmp/hirs_add_aca_tls_path_to_os.sh && \
echo "cp /etc/hirs/certificates/HIRS/ecc_512_sha384_certs/HIRS_leaf_ca3_ecc_512_sha384.pem /etc/pki/ca-trust/source/anchors/" >> /tmp/hirs_add_aca_tls_path_to_os.sh && \
echo "update-ca-trust" >> /tmp/hirs_add_aca_tls_path_to_os.sh
RUN chmod +x /tmp/hirs_add_aca_tls_path_to_os.sh
# The container will report a health state based on when embedded tomcat finishes loading. If the ACA isn't loaded after the timeout, the container will report that it is unhealthy.
HEALTHCHECK --start-period=50s --interval=1s --timeout=90s CMD curl -f https://localhost:8443/HIRS_AttestationCAPortal/portal/index
# Reset working directory
WORKDIR /hirs
# On container launch, the database will be set up. Then bootRun should utilize build artifacts stored in the image.
CMD ["bash", "-c", "/hirs/package/scripts/aca/aca_setup.sh --unattended && /tmp/hirs_add_aca_tls_path_to_os.sh && /hirs/package/scripts/aca/aca_bootRun.sh"]

View File

@ -0,0 +1,80 @@
FROM mcr.microsoft.com/powershell:latest
LABEL org.opencontainers.image.vendor NSA Laboratory for Advanced Cybersecurity Research
LABEL org.opencontainers.image.source https://github.com/nsacyber/hirs
LABEL org.opencontainers.image.description NSA\'s HIRS Attestation Certificate Authority in a Windows-native image. Expose port 8443 to access the portal from outside the container.
SHELL ["pwsh", "-Command"]
# Output Powershell Version
# This Dockerfile requires Powershell 7+.
RUN $PSVersionTable
# Set up logging area
RUN mkdir -p C:/ProgramData/hirs/aca
RUN mkdir -p C:/ProgramData/hirs/log
# Download and install Java 17
RUN ((New-Object System.Net.WebClient).DownloadFile('https://download.oracle.com/java/17/archive/jdk-17.0.8_windows-x64_bin.exe', 'C:/jdk-17.0.8_windows-x64_bin.exe'))
RUN Write-Host "Installing JDK..."
RUN ./jdk-17.0.8_windows-x64_bin.exe /s
RUN Write-Host "Finished installing JDK."
RUN ls 'C:\Program Files\Java'
RUN ls 'C:\Program Files\Java\jdk-17\'
# Download and install Mariadb as a service
RUN ((New-Object System.Net.WebClient).DownloadFile('https://ftp.osuosl.org/pub/mariadb/mariadb-11.1.2/winx64-packages/mariadb-11.1.2-winx64.msi', 'C:/mariadb-11.1.2-winx64.msi'))
RUN Write-Host "Installing MariaDB..."
# mariadb silent install options https://mariadb.com/kb/en/installing-mariadb-msi-packages-on-windows/
RUN Start-Process -Wait -FilePath msiexec.exe -ArgumentList @('/i', 'C:\mariadb-11.1.2-winx64.msi', 'ADDLOCAL=ALL', 'REMOVE=HeidiSQL', 'SERVICENAME=MariaDB', '/qn', '/L*V', 'C:/ProgramData/hirs/log/mariadb_install.log')
RUN Write-Host "Finished installing mariadb."
RUN ls 'C:\Program Files'
RUN ls 'C:\Program Files\MariaDB 11.1'
# Download and install Git
RUN ((New-Object System.Net.WebClient).DownloadFile('https://github.com/git-for-windows/git/releases/download/v2.42.0.windows.2/Git-2.42.0.2-64-bit.exe', 'C:/Git-2.42.0.2-64-bit.exe'))
RUN Write-Host "Installing Git..."
RUN Start-Process -FilePath 'C:/Git-2.42.0.2-64-bit.exe' -ArgumentList \"/VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /o:PathOption=CmdTools /o:BashTerminalOption=ConHost /o:EnableSymlinks=Enabled /COMPONENTS=gitlfs\" -Wait -PassThru
# Disable GCM machine-wide
RUN [Environment]::SetEnvironmentVariable('GCM_INTERACTIVE', 'Never', [System.EnvironmentVariableTarget]::Machine)
RUN Write-Host "Finished installing Git."
# Expose ACA Port
EXPOSE 8443 8080
# Set Environment Variables
RUN setx JAVA_HOME 'C:\Program Files\Java\jdk-17'
RUN setx GIT_HOME 'C:\Program Files\Git'
RUN setx PATH '%JAVA_HOME%\bin;C:\Program Files\MariaDB 11.1\bin;%GIT_HOME%\bin;%PATH%'
# Echo System Variables
RUN echo $Env:PATH
RUN echo $Env:GIT_HOME
RUN echo $Env:JAVA_HOME
# Clone HIRS main
WORKDIR C:/
RUN git config --global --add core.autocrlf false
RUN git config --global --add safe.directory '*'
RUN git clone -b v3_windows-package-scripts https://github.com/nsacyber/hirs.git C:/repo
# Defensive copy of the repo so it's easy to start fresh if needed
WORKDIR C:/repo
RUN cp -Recurse -Force C:/repo C:/hirs
# Ensure Windows configuration files are in place before build.
WORKDIR C:/hirs
RUN pwsh -Command pwsh -ExecutionPolicy Bypass ./package/win/aca/aca_win_config.ps1
# Run bootWar to cache build objects and dependencies
WORKDIR C:/hirs
RUN setx GRADLE_OPTS '-Dorg.gradle.daemon=false'
RUN ./gradlew.bat clean bootWar 2>&1 | tee -a C:/ProgramData/hirs/log/hirs_build.log
RUN cp ./HIRS_AttestationCAPortal/src/main/resources/application.win.properties C:/ProgramData/hirs/aca/
# Run ACA Setup- PKI and DB
WORKDIR C:/hirs
RUN pwsh -Command pwsh -ExecutionPolicy Bypass ./package/win/aca/aca_setup.ps1 -unattended
CMD ["pwsh", "-Command", "pwsh -ExecutionPolicy Bypass C:/hirs/package/win/aca/aca_bootRun.ps1"]

View File

@ -0,0 +1,31 @@
version: "3.9"
services:
aca: # policy settings not saved, will have a clean database/default policy on each boot for now
image: ghcr.io/nsacyber/hirs/aca:alpha2
container_name: aca
ports:
- "8443:8443"
networks:
hat_network:
ipv4_address: 172.16.1.75
hat:
image: ghcr.io/nsacyber/hirs/hat:alpha4
container_name: hat
ports:
- 53:53/tcp
- 53:53/udp
- 67:67/udp
- 68:68/udp
- 69:69
- 80:80
networks:
hat_network:
ipv4_address: 172.16.1.3
networks:
hat_network:
driver: transparent
name: hat_network
ipam:
config:
- subnet: 172.16.1.0/24
gateway: 172.16.1.1

View File

@ -14,6 +14,7 @@ import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -28,8 +29,14 @@ import java.security.cert.X509Certificate;
* Restful implementation of the {@link AttestationCertificateAuthority}. * Restful implementation of the {@link AttestationCertificateAuthority}.
* Exposes the ACA methods as REST endpoints. * Exposes the ACA methods as REST endpoints.
*/ */
@PropertySource(value = "file:/etc/hirs/aca/application.properties", @PropertySources({
// detects if file exists, if not, ignore errors
@PropertySource(value = "file:/etc/hirs/aca/application.properties",
ignoreResourceNotFound = true),
@PropertySource(value = "file:C:/ProgramData/hirs/aca/application.win.properties",
ignoreResourceNotFound = true) ignoreResourceNotFound = true)
})
@RestController @RestController
@RequestMapping("/HIRS_AttestationCA") @RequestMapping("/HIRS_AttestationCA")
public class RestfulAttestationCertificateAuthority extends AttestationCertificateAuthority implements RestfulInterface { public class RestfulAttestationCertificateAuthority extends AttestationCertificateAuthority implements RestfulInterface {

View File

@ -53,6 +53,10 @@ import java.util.Properties;
// detects if file exists, if not, ignore errors // detects if file exists, if not, ignore errors
@PropertySource(value = "file:/etc/hirs/aca/aca.properties", @PropertySource(value = "file:/etc/hirs/aca/aca.properties",
ignoreResourceNotFound = true),
@PropertySource(value = "file:/etc/hirs/aca/application.properties",
ignoreResourceNotFound = true),
@PropertySource(value = "file:C:/ProgramData/hirs/aca/application.win.properties",
ignoreResourceNotFound = true) ignoreResourceNotFound = true)
}) })
@ComponentScan({"hirs.attestationca.portal", "hirs.attestationca.portal.page.controllers", "hirs.attestationca.persist", "hirs.attestationca.persist.entity", "hirs.attestationca.persist.service"}) @ComponentScan({"hirs.attestationca.portal", "hirs.attestationca.portal.page.controllers", "hirs.attestationca.persist", "hirs.attestationca.persist.entity", "hirs.attestationca.persist.service"})

View File

@ -0,0 +1,52 @@
# Logging Config (tomcat may have further config)
logging.level.org.springframework=TRACE
logging.level.org.apache.catalina=TRACE
logging.level.org.springframework.web=TRACE
logging.level.org.hibernate=ERROR
logging.file.path=C:/ProgramData/hirs/log
logging.file.name=hirs.spring.log
# Database Config
spring.jpa.hibernate.ddl-auto=update
jakarta.persistence.sharedCache.mode = UNSPECIFIED
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
aca.certificates.validity = 3652
# Tomcat Config
server.tomcat.additional-tld-skip-patterns=jakarta.persistence-api*.jar, jakarta.xml.bind-api*.jar, txw2*.jar, *commons*.jar, *annotations*.jar, *checker*.jar, *lombok*.jar, *jsr*.jar, *guava*.jar, *access*.jar, *activation*.jar, *bcprov*.jar, *bcmail*.jar, *bcutil*.jar, *bcpkix*.jar, *json*.jar
server.tomcat.basedir=C:/ProgramData/hirs/embeddedtomcat
server.servlet.register-default-servlet=true
server.servlet.context-path=/
spring.mvc.servlet.path=/
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.directory=C:/ProgramData/hirs/log
server.tomcat.accesslog.file-date-format=yyyy-MM-dd
server.tomcat.accesslog.prefix=Tomcat_accesslog_
server.tomcat.accesslog.suffix=.log
server.tomcat.accesslog.rotate=true
# Tomcat TLS support
server.port=8443
server.ssl.enabled=true
server.ssl.trust-store-type=JKS
server.ssl.trust-store=C:/ProgramData/hirs/certificates/HIRS/TrustStore.jks
server.ssl.trust-alias=hirs_aca_tls_rsa_3k_sha384
server.ssl.key-store-type=JKS
server.ssl.key-store=C:/ProgramData/hirs/certificates/HIRS/KeyStore.jks
server.ssl.key-alias=hirs_aca_tls_rsa_3k_sha384
#--server.ssl.key-store-password=123456
#--server.ssl.trust-store-password=123456
#jdbc.driverClassName = com.mysql.cj.jdbc.Driver
#jdbc.url = jdbc:mysql://localhost:3306/hirs_db?autoReconnect=true&useSSL=false
#jdbc.username = root
#jdbc.password = hirspass
#entitymanager.packagesToScan: hirs.attestationca.portal.page.controllers
#spring.jpa.hibernate.ddl-auto=update
#spring.jpa.show-sql=true
# DB dfault password.
#spring.datasource.password=hirs_db

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%C.%M] %-5p : %m%n"/>
</Console>
<RollingFile name="FILE" fileName="C:/ProgramData/hirs/log/HIRS_AttestationCA_Portal.log"
filePattern="C:/ProgramData/hirs/log/HIRS_AttestationCA_Portal.log-%d{yyyy-MM-dd}-%i.log" >
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%C.%M] %-5p : %m%n</pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy
size="10 MB" />
<TimeBasedTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level = "WARN">
<AppenderRef ref="STDOUT" level="WARN" />
<AppenderRef ref="FILE"/>
</Root>
<SpringProfile name="!development, !production">
<Logger name="hirs.attestationca" level="trace" />
</SpringProfile>
<Logger name="org.hibernate" level="DEBUG" />
</Loggers>
<!-- prevents an out-of-memory exception caused by the debug logging of very large inserts -->
<category name="org.hibernate.event.def.AbstractFlushingEventListener">
<priority value="INFO"/>
</category>
</Configuration>

View File

@ -0,0 +1,37 @@
# General notes:
# Properties are processed using an expression processor. That said, properties can inherit the
# values of other properties.
#
# In example the processor will resolve the value of aca.both as 'hello world!'.
# aca.hello = hello
# aca.world = world!
# aca.both = ${aca.hello} ${aca.world}
#
# ACA Directories
# root: the root directory of ACA related files
# certificates: the directory for ACA certificate files
aca.directories.root = C:/ProgramData/hirs/aca
aca.directories.certificates = ${aca.directories.root}/certificates
# ACA certificate related properties. These are generic properties that apply to the creation of
# any certificate that the ACA is responsible for creating.
# validity: the number of days that credentials generated by the ACA are valid.
aca.certificates.validity = 3652
# ACA key store properties
# alias: the alias to reference the ACA key and certificate by
# location: the absolute path to the ACA key store.
# password: key store password
aca.keyStore.alias = HIRS_ACA_KEY
aca.keyStore.location = ${aca.directories.certificates}/keyStore.jks
aca.keyStore.password =
# ACA setup/initialization properties. These properties are used exclusively by the ACA
# initialization process. Generally these properties do not need to be modified
#
# keySize: the default key size of the ACA key pair stored within the trust store
# subjectName: the CN of the generate X509 certificate
# expiration: the number of days that the generated X509 certificate will expire
aca.setup.keyStore.keySize = 2048
aca.setup.keyStore.subjectName = HIRS_AttestationCA_Endorsement
aca.setup.keyStore.expiration = ${aca.certificates.validity}

View File

@ -0,0 +1,102 @@
param (
[string]$p, [string]$path = $null,
[switch]$w, [switch]$war = $false,
[switch]$h, [switch]$help = $false
)
$APP_HOME=(Split-Path -parent $PSCommandPath)
$ACA_COMMON_SCRIPT=(Join-Path $APP_HOME 'aca_common.ps1')
$ALG="RSA" # or "ECC"
$GRADLE_WRAPPER='./gradlew'
$DEPLOYED_WAR=$null
# Load other scripts
. $ACA_COMMON_SCRIPT
# Set up log
set_up_log
# Read aca.properties
read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
# Read spring application.properties
read_spring_properties $global:HIRS_DATA_SPRING_PROP_FILE
echo "-----------------------------------------------------------" | WriteAndLog
echo ("Running with these arguments: "+($PSBoundParameters | Out-String)) | WriteAndLog
# Parameter Consolidation
if ($p -and $path -and ($p -ne $path)) {
"-p and --path were given different paths. Use only one." | WriteAndLog
$help=$true
}
if ($p) {
$path = $p
}
$war = $w -or $war
$help = $h -or $help
if(!(New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent())
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
echo "This script requires root. Please run as root"
exit 1
}
if ($help) {
echo " Setup script for the HIRS ACA"
echo " Syntax: powershell -ExecutionPolicy Bypass aca_bootRun.ps1 [-h|p|w|--path|--war]"
echo " options:"
echo " -p | --path Path to the HIRS_AttestationCAPortal.war file"
echo " -w | --war Use deployed war file"
echo " -h | --help Print this help"
exit 1
}
if ($path) {
$DEPLOYED_WAR = $path
}
# if ($ALG -eq "RSA") {
# $CERT_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
# $CLIENT_DB_P12=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.p12')
# $ALIAS="hirs_aca_tls_rsa_3k_sha384"
# } elseif ($ALG -eq "ECC") {
# $CERT_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_ecc_512_sha384_Cert_Chain.pem')
# $CLIENT_DB_P12=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_client_ecc_512_sha384.p12')
# $ALIAS="hirs_aca_tls_ecc_512_sha384"
# }
if (![System.IO.Directory]::Exists($global:HIRS_DATA_CERTIFICATES_HIRS_DIR)) {
echo "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR directory does not exist. Please run aca_setup\.ps1 and try again."
exit 1;
}
if (!$DEPLOYED_WAR) {
if (![System.IO.File]::Exists($GRADLE_WRAPPER)) {
echo 'This script is expected to be run from the HIRS top level project directory. Exiting.'
exit 1;
}
$DEPLOYED_WAR='./HIRS_AttestationCAPortal/build/libs/HIRS_AttestationCAPortal.war'
}
# Run the embedded tomcat server with Web TLS enabled and database client TLS enabled by overrding critical parameters
# Note "&" is a sub parameter continuation, space represents a new parameter. Spaces and quotes matter.
# hibernate.connection.url is used for the DB connector which established DB TLS connectivity
# server.ssl arguments support the embeded tomcats use of TLS for the ACA Portal
#$CONNECTOR_PARAMS="--hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&user="+$global:ACA_PROPERTIES.'hirs_db_username'+"&password="+$global:ACA_PROPERTIES.'hirs_db_password'+"&sslMode=VERIFY_CA&serverSslCert=$CERT_CHAIN&keyStoreType=PKCS12&keyStorePassword="+$global:ACA_PROPERTIES.'hirs_pki_password'+"&keyStore=$CLIENT_DB_P12" | ChangeBackslashToForwardSlash
#$WEB_TLS_PARAMS="--server.ssl.key-store-password="+$global:ACA_PROPERTIES.'hirs_pki_password'+
#" --server.ssl.trust-store-password="+$global:ACA_PROPERTIES.'hirs_pki_password' | ChangeBackslashToForwardSlash
$SPRING_PROP_FILE_FORWARDSLASHES=($global:HIRS_DATA_SPRING_PROP_FILE | ChangeBackslashToForwardSlash)
#echo $CONNECTOR_PARAMS
#echo $WEB_TLS_PARAMS
if ($w -or $war) {
echo "Booting the ACA from a war file..." | WriteAndLog
java -jar $DEPLOYED_WAR --spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES
} else {
echo "Booting the ACA from local build..." | WriteAndLog
./gradlew bootRun --args="--spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES"
}

View File

@ -0,0 +1,224 @@
# Globally set options
# HIRS System directories, if installed via MSI
# C:\Program Files\hirs # Executables
# bin
# HIRS_AttestationCA_Portal.war
# scripts
# See HIRS Relative directories description below
# HIRS Data directories, installed by these scripts
# C:\ProgramData\hirs # Configuration Files, Logs
# aca
# certificates
# HIRS
# ecc_512_sha384_certs
# rsa_3k_sha384_certs
# json
# log
# Other files needed:
# C:/MariaDB 11.1/data/my.ini
# If mysql is installed somewhere else, update DB_CONF below.
$global:HIRS_SYS_HOME=(Join-Path $Env:ProgramFiles "hirs")
$global:HIRS_INSTALL_SCRIPTS_DIR=(Join-Path $Env:ProgramFiles "scripts")
$global:HIRS_INSTALL_SCRIPTS_DB_DIR=(Join-Path $Env:ProgramFiles "db")
$global:HIRS_DATA_DIR=(Join-Path $Env:ProgramData "hirs")
$global:HIRS_CONF_DIR=(Join-Path $global:HIRS_DATA_DIR "aca")
$global:HIRS_DATA_ACA_PROPERTIES_FILE=(Join-Path $global:HIRS_CONF_DIR 'aca.properties')
$global:HIRS_DATA_SPRING_PROP_FILE=(Join-Path $global:HIRS_CONF_DIR 'application.win.properties')
$global:HIRS_DATA_CERTIFICATES_DIR=(Join-Path $global:HIRS_DATA_DIR "certificates")
$global:HIRS_DATA_CERTIFICATES_HIRS_DIR=(Join-Path $global:HIRS_DATA_CERTIFICATES_DIR "HIRS")
$global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH=(Join-Path $HIRS_DATA_CERTIFICATES_HIRS_DIR "rsa_3k_sha384_certs")
$global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH=(Join-Path $HIRS_DATA_CERTIFICATES_HIRS_DIR "ecc_512_sha384_certs")
$global:HIRS_DATA_LOG_DIR=(Join-Path $global:HIRS_DATA_DIR "log")
$global:HIRS_DATA_INSTALL_LOG_NAME=(Join-Path $global:HIRS_DATA_LOG_DIR ("hirs_aca_install_"+(Get-Date -Format "yyyy-MM-dd")+'.log'))
$global:HIRS_DATA_JSON_DIR=(Join-Path $global:HIRS_DATA_DIR "json")
# Db Configuration files
$global:DB_CONF=(Join-Path $Env:ProgramFiles 'MariaDB 11.1' 'data' 'my.ini')
# Default Server Side Certificates
$global:SSL_DB_SRV_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
$global:SSL_DB_SRV_CERT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_srv_rsa_3k_sha384.pem')
$global:SSL_DB_SRV_KEY=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_srv_rsa_3k_sha384.key')
# Default Client Side Certificates
$global:SSL_DB_CLIENT_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
$global:SSL_DB_CLIENT_CERT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.pem')
$global:SSL_DB_CLIENT_KEY=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.key')
# HIRS Relative directories assumed structure
# package
# scripts
# aca
# db
# db_create.sql
# secure_mysql.sql
# pki
# ca.conf
# win
# aca
# aca_bootRun.ps1
# aca_common.ps1 # This script. You are here.
# aca_setup.ps1
# aca_win_config.ps1
# db
# db_create.ps1
# mysql_util.ps1
# pki
# pki_chain_gen.ps1
# pki_setup.ps1
$global:HIRS_REL_WIN_ACA_HOME=(Split-Path -parent $PSCommandPath)
$global:HIRS_REL_WIN_HOME=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME ..)
$global:HIRS_REL_PACKAGE_HOME=(Join-Path -Resolve $global:HIRS_REL_WIN_HOME ..)
$global:HIRS_REL_SCRIPTS_HOME=(Join-Path -Resolve $global:HIRS_REL_PACKAGE_HOME 'scripts')
$global:HIRS_REL_SCRIPTS_ACA_HOME=(Join-Path -Resolve $global:HIRS_REL_SCRIPTS_HOME 'aca')
$global:HIRS_REL_SCRIPTS_DB_HOME=(Join-Path -Resolve $global:HIRS_REL_SCRIPTS_HOME 'db')
$global:HIRS_REL_SCRIPTS_DB_CREATE_SQL=(Join-Path -Resolve $global:HIRS_REL_SCRIPTS_DB_HOME 'db_create.sql')
$global:HIRS_REL_SCRIPTS_DB_SECURE_MYSQL_SQL=(Join-Path -Resolve $global:HIRS_REL_SCRIPTS_DB_HOME 'secure_mysql.sql')
$global:HIRS_REL_SCRIPTS_PKI_HOME=(Join-Path -Resolve $global:HIRS_REL_SCRIPTS_HOME 'pki')
$global:HIRS_REL_SCRIPTS_PKI_CA_CONF=(Join-Path -Resolve $global:HIRS_REL_SCRIPTS_PKI_HOME 'ca.conf')
$global:HIRS_REL_WIN_ACA_BOOTRUN=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_bootRun.ps1')
$global:HIRS_REL_WIN_ACA_COMMON=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_common.ps1')
$global:HIRS_REL_WIN_ACA_SETUP=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_setup.ps1')
$global:HIRS_REL_WIN_ACA_SETUP=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_win_config.ps1')
$global:HIRS_REL_WIN_DB_HOME=(Join-Path -Resolve $global:HIRS_REL_WIN_HOME 'db')
$global:HIRS_REL_WIN_DB_CREATE=(Join-Path -Resolve $global:HIRS_REL_WIN_DB_HOME 'db_create.ps1')
$global:HIRS_REL_WIN_DB_MYSQL_UTIL=(Join-Path -Resolve $global:HIRS_REL_WIN_DB_HOME 'mysql_util.ps1')
$global:HIRS_REL_WIN_PKI_HOME=(Join-Path -Resolve $global:HIRS_REL_WIN_HOME 'pki')
$global:HIRS_REL_WIN_PKI_CHAIN_GEN=(Join-Path -Resolve $global:HIRS_REL_WIN_PKI_HOME 'pki_chain_gen.ps1')
$global:HIRS_REL_WIN_PKI_SETUP=(Join-Path -Resolve $global:HIRS_REL_WIN_PKI_HOME 'pki_setup.ps1')
# Saved values
# $Env:HIRS_MYSQL_ROOT_PWD
# $Env:HIRS_PKI_PWD
$global:ACA_PROPERTIES=$null
$global:SPRING_PROPERTIES=$null
# Common utility functions
Function read_aca_properties () {
# This converts the ACA properties file into a hash table
# Values are accessed by key like this: $propertyValue=$global:ACA_PROPERTIES.'example.property.key'
param (
[string]$file = $null
)
if (!$global:ACA_PROPERTIES -and $file -and [System.IO.File]::Exists($file)) {
$file_content=(Get-Content $file -Raw)
if ($file_content) { # File is not empty
# $file_content=([Regex]::Escape($file_content) -replace "(\\r)?\\n",[Environment]::NewLine)
# $global:ACA_PROPERTIES=(ConvertFrom-StringData($file_content))
$global:ACA_PROPERTIES=(Get-Content -Path $file -Raw | ConvertFrom-StringData)
} else { # File is empty
# Initialize empty hash table
$global:ACA_PROPERTIES=@{}
}
} elseif ($file -and ![System.IO.File]::Exists($file)) {
$msg="Warning: ACA properties file not found. The path provided was: $file"
if ($global:LOG_FILE) {
echo "$msg" | WriteAndLog
} else {
Write-Host "$msg"
}
}
}
Function add_new_aca_property () {
param (
[string]$file = $null,
[string]$newKeyAndValue = $null
)
if ($global:ACA_PROPERTIES -and $file -and $newKeyAndValue -and [System.IO.File]::Exists($file)) {
$msg="Writing KeyValue pair to $file"
if ($global:LOG_FILE) {
echo "$msg" | WriteAndLog
} else {
Write-Host "$msg"
}
Write-Host "NOT LOGGED: KeyValue pair: $newKeyAndValue to file $file"
echo "$newKeyAndValue" >> $file
$global:ACA_PROPERTIES=$null
read_aca_properties $file
}
}
Function read_spring_properties () {
# This converts the application properties file into a hash table
# Values are accessed by key like this: $propertyValue=$global:SPRING_PROPERTIES.'example.property.key'
param (
[string]$file = $null
)
if (!$global:SPRING_PROPERTIES -and $file -and [System.IO.File]::Exists($file)) {
$file_content=(Get-Content $file -Raw)
if ($file_content) { # File is not empty
#$file_content=([Regex]::Escape($file_content) -replace "(\\r)?\\n",[Environment]::NewLine)
#$global:SPRING_PROPERTIES=(ConvertFrom-StringData($file_content))
$global:SPRING_PROPERTIES=(Get-Content -Path $file -Raw | ConvertFrom-StringData)
} else { # File is empty
# Initialize empty hash table
$global:SPRING_PROPERTIES=@{}
}
} elseif ($file -and ![System.IO.File]::Exists($file)) {
$msg="Warning: Spring properties file not found. The path provided was: $file"
if ($global:LOG_FILE) {
echo "$msg" | WriteAndLog
} else {
Write-Host "$msg"
}
}
}
Function add_new_spring_property () {
param (
[string]$file = $null,
[string]$newKeyAndValue = $null
)
if ($global:SPRING_PROPERTIES -and $file -and $newKeyAndValue -and [System.IO.File]::Exists($file)) {
$msg="Writing KeyValue pair to $file"
if ($global:LOG_FILE) {
echo "$msg" | WriteAndLog
} else {
Write-Host "$msg"
}
Write-Host "NOT LOGGED: KeyValue pair: $newKeyAndValue to file $file"
echo "$newKeyAndValue" >> $file
$global:SPRING_PROPERTIES=$null
read_spring_properties $file
}
}
Function create_random () {
return (1..100 | % { Get-Random } | sha512sum | tr -dc 'a-zA-Z0-9')
}
Function set_up_log () {
if (![System.IO.Directory]::Exists($global:HIRS_DATA_LOG_DIR)) {
mkdir -p $global:HIRS_DATA_LOG_DIR 2>&1 > $null
}
$global:LOG_FILE=$global:HIRS_DATA_INSTALL_LOG_NAME
touch $global:LOG_FILE
}
Function print_all_variables () {
# intended for debugging
# this will print all variables and their values in the current context
Get-Variable | Out-String
}
Function WriteAndLog () {
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position=0)]
[string]$msg
)
# EXPECTS set_up_log() to be run and $global:LOG_FILE to be defined
Write-Host "$msg"
"$msg" >> "$global:LOG_FILE"
}
Function ChangeBackslashToForwardSlash () {
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position=0)]
[string]$msg
)
echo ($msg -replace "\\","/")
}
Function ChangeFileBackslashToForwardSlash () {
param(
[string]$file = $null
)
(Get-Content $file) -replace "\\","/" | Set-Content $file
}

View File

@ -0,0 +1,97 @@
param (
[switch]$sd, [switch]${skip-db} = $false,
[switch]$sp, [switch]${skip-pki} = $false,
[switch]$u, [switch]$unattended = $false,
[switch]$h, [switch]$help = $false
)
$APP_HOME=(Split-Path -parent $PSCommandPath)
$ACA_COMMON_SCRIPT=(Join-Path $APP_HOME 'aca_common.ps1')
$COMP_JSON=(Join-Path $APP_HOME '..' '..' '..' 'HIRS_AttestationCA' 'src' 'main' 'resources' 'component-class.json')
$VENDOR_TABLE=(Join-Path $APP_HOME '..' '..' '..' 'HIRS_AttestationCA' 'src' 'main' 'resources' 'vendor-table.json')
# Load other scripts
. $ACA_COMMON_SCRIPT
# Set up log
set_up_log
echo "-----------------------------------------------------------" | WriteAndLog
echo "ACA setup log file is $global:LOG_FILE" | WriteAndLog
echo ("Running with these arguments: "+($PSBoundParameters | Out-String)) | WriteAndLog
# Read aca.properties
mkdir -F -p $global:HIRS_CONF_DIR 2>&1 > $null
mkdir -F -p $global:HIRS_DATA_JSON_DIR 2>&1 > $null
mkdir -F -p $global:HIRS_DATA_LOG_DIR 2>&1 > $null
#cp $COMP_JSON $global:HIRS_JSON_DIR
#cp $VENDOR_TABLE $global:HIRS_JSON_DIR
touch $global:HIRS_DATA_ACA_PROPERTIES_FILE # create it, if it doesn't exist
read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
# Read spring application.properties
touch $global:HIRS_DATA_SPRING_PROP_FILE # create it, if it doesn't exist
read_spring_properties $global:HIRS_DATA_SPRING_PROP_FILE
# Parameter Consolidation
$skipdb=$sd -or ${skip-db}
$skippki=$sp -or ${skip-pki}
$unattended=$u -or $unattended
$help = $h -or $help
if ($help) {
echo " Setup script for the HIRS ACA"
echo " Syntax: sh aca_setup.sh [-u|h|sd|sp|--skip-db|--skip-pki]"
echo " options:"
echo " -u | --unattended Run unattended"
echo " -h | --help Print this Help."
echo " -sp | --skip-pki run the setup without pki setup."
echo " -sb | --skip-db run the setup without database setup."
exit 1
}
if(!(New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent())
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
echo "This script requires root. Please run as root"
exit 1
}
echo "HIRS ACA Setup initiated on $(date +%Y-%m-%d)" | WriteAndLog
if (!$skippki) {
if (!$Env:HIRS_PKI_PWD) {
$HIRS_PKI_PWD=(create_random)
# NOTE: Writing to the environment variable did not work within the container
# This password will be stored in the ACA properties file.
echo "Using randomly generated password for the PKI key password" | WriteAndLog
Write-Host "NOT LOGGED: Using pki password=$HIRS_PKI_PWD"
} else {
$HIRS_PKI_PWD=$Env:HIRS_PKI_PWD
echo "Using system supplied password for the PKI key password" | WriteAndLog
}
pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_PKI_SETUP -LOG_FILE:"$global:LOG_FILE" -PKI_PASS:"$HIRS_PKI_PWD" -UNATTENDED:"$unattended"
if ($LastExitCode -eq 0) {
echo "ACA PKI setup complete" | WriteAndLog
} else {
echo "Error setting up ACA PKI" | WriteAndLog
exit 1
}
} else {
echo ("ACA PKI setup not run due to presence of command line argument: "+($PSBoundParameters.Keys | grep -E "skip-pki|sp")) | WriteAndLog
}
if (!$skipdb) {
pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_DB_CREATE -LOG_FILE:"$global:LOG_FILE" -UNATTENDED:"$unattended"
if ($LastExitCode -eq 0) {
echo "ACA database setup complete" | WriteAndLog
} else {
echo "Error setting up ACA DB" | WriteAndLog
exit 1
}
} else {
echo ("ACA Database setup not run due to command line argument: "+($PSBoundParameters.Keys | grep -E "skip-db|sd")) | WriteAndLog
}
echo "ACA setup complete" | WriteAndLog

View File

@ -0,0 +1,28 @@
# This script is intended to only be run from within a cloned copy of the HIRS repository from GitHub. It is not meant to be deployed.
# This script swaps configuration files for Windows into place.
$APP_HOME=(Split-Path -parent $PSCommandPath)
$ACA_COMMON_SCRIPT=(Join-Path $APP_HOME 'aca_common.ps1')
# Load other scripts
. $ACA_COMMON_SCRIPT
# Set up paths to configuration files
$global:HIRS_REL_PORTAL_LOG4J_SPRING_XML=(Join-Path -Resolve $global:HIRS_REL_PACKAGE_HOME .. HIRS_AttestationCAPortal src main resources log4j2-spring.xml)
$global:HIRS_REL_PORTAL_APPLICATION_PROPERTIES=(Join-Path -Resolve $global:HIRS_REL_PACKAGE_HOME .. HIRS_AttestationCAPortal src main resources application.properties)
$global:HIRS_REL_PORTAL_LOG4J_SPRING_LINUX_XML=(Join-Path $global:HIRS_REL_PACKAGE_HOME .. HIRS_AttestationCAPortal src main resources log4j2-spring.linux.xml)
$global:HIRS_REL_PORTAL_APPLICATION_LINUX_PROPERTIES=(Join-Path $global:HIRS_REL_PACKAGE_HOME .. HIRS_AttestationCAPortal src main resources application.linux.properties)
$global:HIRS_REL_PORTAL_LOG4J_SPRING_WIN_XML=(Join-Path -Resolve $global:HIRS_REL_PACKAGE_HOME .. HIRS_AttestationCAPortal src main resources log4j2-spring.win.xml)
$global:HIRS_REL_PORTAL_APPLICATION_WIN_PROPERTIES=(Join-Path -Resolve $global:HIRS_REL_PACKAGE_HOME .. HIRS_AttestationCAPortal src main resources application.win.properties)
$global:HIRS_REL_WIN_PKI_CA_CONF=(Join-Path $global:HIRS_REL_WIN_PKI_HOME 'ca.conf')
# Back up linux configuration files
mv $global:HIRS_REL_PORTAL_LOG4J_SPRING_XML $global:HIRS_REL_PORTAL_LOG4J_SPRING_LINUX_XML
mv $global:HIRS_REL_PORTAL_APPLICATION_PROPERTIES $global:HIRS_REL_PORTAL_APPLICATION_LINUX_PROPERTIES
# Copy windows configuration files in place
cp $global:HIRS_REL_PORTAL_LOG4J_SPRING_WIN_XML $global:HIRS_REL_PORTAL_LOG4J_SPRING_XML
cp $global:HIRS_REL_PORTAL_APPLICATION_WIN_PROPERTIES $global:HIRS_REL_PORTAL_APPLICATION_PROPERTIES
# Make a copy of the ca.conf file local to the windows scripts
cp $global:HIRS_REL_SCRIPTS_PKI_CA_CONF $global:HIRS_REL_WIN_PKI_CA_CONF

View File

@ -0,0 +1,188 @@
#!/bin/bash
#
###############################################################################
# HIRS DB creation
# Environment variables used:
# a. HIRS_MYSQL_ROOT_PWD: Set this variable if mysql root password is already set
# b. HIRS_DB_PWD: Set the pwd if default password to hirs_db user needs to be changed
################################################################################
param (
[string]$LOG_FILE = $null,
[switch]$unattended = $false
)
$APP_HOME=(Split-Path -parent $PSCommandPath)
$ACA_COMMON_SCRIPT=(Join-Path "$APP_HOME" .. aca aca_common.ps1)
# Load other scripts
. $ACA_COMMON_SCRIPT
. $global:HIRS_REL_WIN_DB_MYSQL_UTIL
# Read aca.properties
read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
# Read spring application.properties
read_spring_properties $global:HIRS_DATA_SPRING_PROP_FILE
# Parameter check
if ($LOG_FILE) {
touch $LOG_FILE
$global:LOG_FILE=$LOG_FILE
} else {
set_up_log
}
touch $global:HIRS_DATA_ACA_PROPERTIES_FILE
touch $global:DB_CONF
# Make sure required paths exist
mkdir -F -p $global:HIRS_CONF_DIR 2>&1 > $null
mkdir -F -p $global:HIRS_DATA_LOG_DIR 2>&1 > $null
Function check_mysql_root_pwd () {
# Check if DB root password needs to be obtainedS
$DB_ADMIN_PWD=""
if (!$Env:HIRS_MYSQL_ROOT_PWD) {
# Create a 32 character random password
echo "Using randomly generated password for the DB admin" | WriteAndLog
$DB_ADMIN_PWD=(create_random)
Write-Host "NOT LOGGED: DB Admin will be set to $DB_ADMIN_PWD, please make note for next mysql use."
# Check unattended flag set m if not then prompt user for permission ot store mysql root password
if (!$unattended) {
$confirm=Read-Host 'Do you wish to save this password to the aca.properties file?'
if (($confirm -eq "y") -or ($confirm -eq "yes")) { # case-insensitive
add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"mysql_admin_password=$DB_ADMIN_PWD"
echo "Mysql root password saved locally" | WriteAndLog
} else {
echo "Mysql root password not saved locally" | WriteAndLog
}
} else { # unattended install
add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"mysql_admin_password=$DB_ADMIN_PWD"
echo "Mysql root password has been saved locally." | WriteAndLog
}
mysqladmin --user=root password "$DB_ADMIN_PWD"
} else {
$DB_ADMIN_PWD=$Env:HIRS_MYSQL_ROOT_PWD
echo "Using system variable supplied password" | WriteAndLog
}
# Make sure root password is correct
mysql -u root -p"$DB_ADMIN_PWD" -e 'quit' 2>&1 | WriteAndLog
if ($LastExitCode -eq 0) {
echo "Mysql root password verified" | WriteAndLog
} else {
echo "MYSQL root password was not the default, not supplied, or was incorrect" | WriteAndLog
echo " please set the HIRS_MYSQL_ROOT_PWD system variable and retry." | WriteAndLog
echo " ********** ACA Mysql setup aborted ********" | WriteAndLog
exit 1
}
return $DB_ADMIN_PWD
}
Function set_mysql_tls () {
# Check DB server setup. If ssl params dont exist then we need to add them.
if (!(Get-Content $global:DB_CONF | grep "ssl")) {
# Add TLS files to my.ini- Assumes [client] section at the end, and no [server] section
echo "Updating $global:DB_CONF with ssl parameters..." | WriteAndLog
echo "ssl_ca=$SSL_DB_CLIENT_CHAIN" >> $global:DB_CONF
echo "ssl_cert=$SSL_DB_CLIENT_CERT" >> $global:DB_CONF
echo "ssl_key=$SSL_DB_CLIENT_KEY" >> $global:DB_CONF
echo "[server]" >> $global:DB_CONF
echo "ssl_ca=$global:SSL_DB_SRV_CHAIN" >> $global:DB_CONF
echo "ssl_cert=$global:SSL_DB_SRV_CERT" >> $global:DB_CONF
echo "ssl_key=$global:SSL_DB_SRV_KEY" >> $global:DB_CONF
ChangeFileBackslashToForwardSlash $global:DB_CONF
} else {
echo "$global:DB_CONF contains existing entry for ssl, skipping..." | WriteAndLog
}
}
# Process HIRS DB USER
Function set_hirs_db_pwd () {
param (
[string]$DB_ADMIN_PWD = $null
)
if (!$DB_ADMIN_PWD) {
echo "set_hirs_db_pwd was called without supplying a required variable" | WriteAndLog
}
$HIRS_PASS=""
if ($Env:HIRS_DB_PWD) {
$HIRS_PASS=$Env:HIRS_DB_PWD
echo "Using hirs_db password found in the environment variable HIRS_DB_PWD" | WriteAndLog
} elseif ($global:ACA_PROPERTIES.'hirs_db_password') {
$HIRS_PASS=$global:ACA_PROPERTIES.'hirs_db_password'
echo "Using hirs_db password found in the ACA properties file $global:HIRS_DATA_ACA_PROPERTIES_FILE" | WriteAndLog
} else {
echo "Using randomly generated password for the DB key password" | WriteAndLog
$HIRS_PASS=(create_random)
add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"hirs_db_username=hirs_db"
add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"hirs_db_password=$HIRS_PASS"
echo "Stored hirs_db password in the ACA properties file $global:HIRS_DATA_ACA_PROPERTIES_FILE" | WriteAndLog
}
$RESULT=(mysql -u root -p"$DB_ADMIN_PWD" -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'hirs_db')")
if ($RESULT -eq 1) {
echo "hirs-db user exists" | WriteAndLog
}
return $HIRS_PASS
}
# Create a hirs_db with client side TLS enabled
Function create_hirs_db_with_tls () {
param (
[string]$DB_ADMIN_PWD = $null,
[string]$HIRS_PASS = $null
)
if (!$DB_ADMIN_PWD) {
echo "create_hirs_db_with_tls: DB_ADMIN_PWD not provided and is required" | WriteAndLog
}
if (!$HIRS_PASS) {
echo "create_hirs_db_with_tls: HIRS_PASS not provided and is required" | WriteAndLog
}
# Check if hirs_db not created and create it if it wasn't
mysqlshow -u root -p"$DB_ADMIN_PWD" | grep "hirs_db" 2>&1 > $null
if ($LastExitCode -eq 0) {
echo "hirs_db exists, skipping hirs_db create" | WriteAndLog
} else {
echo "Creating hirs_db database" | WriteAndLog
mysql -u root -p"$DB_ADMIN_PWD" -e "source $global:HIRS_REL_SCRIPTS_DB_CREATE_SQL"
mysql -u root -p"$DB_ADMIN_PWD" -e "source $global:HIRS_REL_SCRIPTS_DB_SECURE_MYSQL_SQL"
mysql -u root -p"$DB_ADMIN_PWD" -e "ALTER USER 'hirs_db'@'localhost' IDENTIFIED BY '$HIRS_PASS'; FLUSH PRIVILEGES;"
}
}
Function create_hibernate_url () {
param (
[string]$ALG = $null
)
if ($ALG -eq "RSA") {
$CERT_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
$CLIENT_DB_P12=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.p12')
$ALIAS="hirs_aca_tls_rsa_3k_sha384"
} elseif ($ALG -eq "ECC") {
$CERT_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_ecc_512_sha384_Cert_Chain.pem')
$CLIENT_DB_P12=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_client_ecc_512_sha384.p12')
$ALIAS="hirs_aca_tls_ecc_512_sha384"
}
$CONNECTOR_URL="hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&user="+$global:ACA_PROPERTIES.'hirs_db_username'+"&password="+$global:ACA_PROPERTIES.'hirs_db_password'+"&sslMode=VERIFY_CA&serverSslCert=$CERT_CHAIN&keyStoreType=PKCS12&keyStorePassword="+$global:ACA_PROPERTIES.'hirs_pki_password'+"&keyStore=$CLIENT_DB_P12" | ChangeBackslashToForwardSlash
# Save connector information to the application properties file.
add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$CONNECTOR_URL"
}
# HIRS ACA Mysqld processing ...
check_mariadb_install -p
check_for_container -p
set_mysql_tls
start_mysqlsd -p
$DB_ADMIN_PWD=check_mysql_root_pwd
$HIRS_PASS=set_hirs_db_pwd -DB_ADMIN_PWD:"$DB_ADMIN_PWD"
create_hirs_db_with_tls -DB_ADMIN_PWD:"$DB_ADMIN_PWD" -HIRS_PASS:"$HIRS_PASS"
create_hibernate_url -ALG:"RSA"
mysqld_reboot -p

View File

@ -0,0 +1,109 @@
Function check_for_container () {
param (
[switch]$p, [switch]$PRINT_STATUS = $false
)
$PRINT_STATUS = $p -or $PRINT_STATUS;
if((Get-ItemProperty -path HKLM:System\CurrentControlSet\Control).ContainerType) {
$global:DOCKER_CONTAINER=$true
} else {
$global:DOCKER_CONTAINER=$false
}
if ($PRINT_STATUS) {
("This {0} running in a container." -f ('is not', 'is')[$global:DOCKER_CONTAINER])
}
}
Function check_mariadb_install () {
param (
[switch]$p, [switch]$PRINT_STATUS = $false
)
$PRINT_STATUS = $p -or $PRINT_STATUS;
if (Get-Command "mysql.exe" -ErrorAction SilentlyContinue) {
$global:MYSQL_INSTALLED=$true
if ($PRINT_STATUS) {
echo "mysql is installed" | WriteAndLog
}
} else {
$global:MYSQL_INSTALLED=$false
if ($PRINT_STATUS) {
echo "mysql is NOT been installed, aborting install" | WriteAndLog
}
exit 1;
}
}
Function start_mysqlsd () {
param (
[switch]$p, [switch]$PRINT_STATUS = $false
)
$PRINT_STATUS = $p -or $PRINT_STATUS
$DB_STATUS=(check_mysql $PRINT_STATUS)
$service=(Get-Service MariaDB -ErrorAction SilentlyContinue)
# Check if mysql is already running, if not initialize
if(!$DB_STATUS -or ($DB_STATUS -and $DB_STATUS.HasExited)) {
if ($PRINT_STATUS) {
echo "Running the mariadb db installer..." | WriteAndLog
}
& mariadb-install-db.exe 2>&1 | WriteAndLog
if ($PRINT_STATUS) {
echo "Attempting to start mysql..." | WriteAndLog
}
if($service -and ($service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Stopped)) {
$service.Start() 2>&1 | WriteAndLog
} else {
Start-Process mysqld.exe -WindowStyle Hidden 2>&1 | WriteAndLog
}
$DB_STATUS=(check_mysql $PRINT_STATUS)
}
}
Function check_mysql () {
param (
[switch]$p, [switch]$PRINT_STATUS = $false
)
$PRINT_STATUS = $p -or $PRINT_STATUS;
$DB_STATUS=(Get-Process -Name mysqld -ErrorAction SilentlyContinue)
if ($PRINT_STATUS) {
("The DB {0} running." -f ('is not', 'is')[$DB_STATUS]) | WriteAndLog
}
return $DB_STATUS;
}
# Removed check_mysql_root: Looked redundant to db_create:check_mysql_root_pwd
Function check_db_cleared () {
mysql -u root -e 'quit' &> $null
if ($LastExitCode -eq 0) {
echo " Empty root password verified" | WriteAndLog
} else {
echo " Mysql Root password is not empty" | WriteAndLog
}
$HIRS_DB_USER_EXISTS=(mysql -uroot -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'hirs_db')")
if ($HIRS_DB_USER_EXISTS -eq 1) {
echo " hirs_db user exists" | WriteAndLog
} else {
echo " hirs_db user does not exist" | WriteAndLog
}
}
Function mysqld_reboot () {
param (
[switch]$p, [switch]$PRINT_STATUS = $false
)
$PRINT_STATUS = $p -or $PRINT_STATUS;
if ($PRINT_STATUS) {
echo "Attempting to restart mysql..." | WriteAndLog
}
if($service) {
$service.Stop() 2>&1 >> "$global:LOG_FILE"
$service.Start() 2>&1 >> "$global:LOG_FILE"
} else {
Start-Process mysqld.exe -WindowStyle Hidden 2>&1 | WriteAndLog
}
}

View File

@ -0,0 +1,292 @@
#!/bin/bash
# Script to generate a PKI Stack (Root, Intermediate, and LEAF CAs) and a Base RIM Signer
# creates a folder based upon the actor name and places certs under an algoithm specific folder (e.g. rsa_certs)
# PARAMS:
# 1. Actor name string (e.g. "Server Manufacturer")
# 2. Algorithm string (e.g. rsa or ecc)
# 3. Key Bit Size string (e.g. 2048)
# 4. Hash Algorithm string (e.g. sha256)
# 5. PKI password used to protect PKI keys and certs
#
# Examples:
# pki_chain_gen.sh "PC Manufacturer" rsa 2048 sha256 "password"
# pki_chain_gen.sh "DISK Manufacturer" ecc 256 sha512 "password"
#
# A KeyStore and Trust Store are created for by Java Applications. Both will use the supplied password.
param (
[string]$ACTOR = $null,
[string]$ASYM_ALG = $null,
[string]$ASYM_SIZE = $null,
[string]$HASH_ALG = $null,
[string]$PASS = $null,
[string]$LOG_FILE = $null
)
$APP_HOME=(Split-Path -parent $PSCommandPath)
$ACA_COMMON_SCRIPT=(Join-Path $APP_HOME '..' 'aca' 'aca_common.ps1')
# Load other scripts
. $ACA_COMMON_SCRIPT
# Read aca.properties
read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
# Parameter check
if (!$ACTOR -or !$ASYM_ALG -or !$ASYM_SIZE -or !$HASH_ALG -or ($ACTOR -eq "-h") -or ($ACTOR -eq "--help")) {
echo "parameter missing to pki_chain_gen.sh, exiting pki setup" | WriteAndLog
exit 1;
}
if ($LOG_FILE) {
$global:LOG_FILE=$LOG_FILE
} else {
set_up_log
}
$ACTOR_ALT=("$ACTOR" -replace " ","_")
$ROOT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test root ca"
$INT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test intermediate ca"
$LEAF_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test ca"
$SIGNER_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test signer"
$SERVER_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR aca"
$TRUSTSTORE="$global:HIRS_DATA_CERTIFICATES_DIR\$ACTOR_ALT\TrustStore.jks"
$TRUSTSTORE_P12="$global:HIRS_DATA_CERTIFICATES_DIR\$ACTOR_ALT\TrustStore.p12"
$KEYSTORE="$global:HIRS_DATA_CERTIFICATES_DIR\$ACTOR_ALT\KeyStore.jks"
if (($ASYM_ALG -ne "rsa") -and ($ASYM_ALG -ne "ecc")) {
echo "$ASYM_ALG is an unsupported assymetric algorithm, exiting pki setup" | WriteAndLog
exit 1;
}
switch ($ASYM_SIZE) {
256 {
$KSIZE="256"
$ECC_NAME="secp256k1"
Break
}
384 {
$KSIZE="384"
$ECC_NAME="secp384r1"
Break
}
512 {
$KSIZE="512"
$ECC_NAME="secp521r1"
Break
}
2048 {
$KSIZE="2k"
Break
}
3072 {
$KSIZE="3k"
Break
}
4096 {
$KSIZE="4k"
Break
}
Default {
echo "$ASYM_SIZE is an unsupported key size, exiting pki setup" | WriteAndLog
exit 1
}
}
# Use algorithm and key size to create unique file paths and Distinguished names
$NAME="$ACTOR $ASYM_ALG $KSIZE $HASH_ALG"
$CERT_FOLDER="$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"+"_certs"
$PKI_ROOT="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_"+"root_ca_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
$PKI_INT="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_intermediate_ca_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
$PKI_CA1="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_leaf_ca1_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
$PKI_CA2="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_leaf_ca2_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
$PKI_CA3="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_leaf_ca3_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
$RIM_SIGNER="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_rim_signer_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
$TLS_SERVER="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_aca_tls_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
$DB_SERVER="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_db_srv_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
$DB_CLIENT="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_db_client"+"_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
$TRUST_STORE_FILE="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"+"_Cert_Chain.pem"
$ROOT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test root ca"
$INT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test intermediate ca"
$LEAF_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test ca"
$SIGNER_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test signer"
$TLS_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME portal"
$DB_SRV_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME DB Server"
$DB_CLIENT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME DB Client"
# Add check for existing folder and halt if it exists
if ([System.IO.Directory]::Exists("$ACTOR_ALT/$CERT_FOLDER")) {
echo "Folder for $CERT_FOLDER exists, exiting..." | WriteAndLog
exit 1
}
# Intialize sub folders
echo "Creating PKI for $ACTOR_ALT using $KSIZE $ASYM_ALG and $HASH_ALG..." | WriteAndLog
mkdir -F -p "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" 2>&1 > $null
mkdir -F -p "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER" 2>&1 > $null
mkdir -F -p "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\certs" 2>&1 > $null
cp "$global:HIRS_DATA_CERTIFICATES_DIR\ca.conf" "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\" | WriteAndLog
touch "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\db"
touch "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\openssl-san.cnf"
if (![System.IO.File]::Exists("$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\serial.txt")) {
echo "01" > "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\serial.txt" | WriteAndLog
}
# Function to add Cert to Truststore and key to Keystore
Function add_to_stores () {
param (
[string]$CERT_PATH = $null
)
$ALIAS=[System.IO.Path]::GetFileName($CERT_PATH) # Use filename without path as an alias
echo "$CERT_PATH key objects will use the alias `"$ALIAS`" in trust stores." | WriteAndLog
echo "Exporting key and certificate to PKCS12." | WriteAndLog
# Add the cert and key to the key store.. make a p12 file to import into te keystore
openssl pkcs12 -export -in "$CERT_PATH.pem" -inkey "$CERT_PATH.key" -out "tmpkey.p12" -passin "pass:$PASS" -macalg SHA256 -keypbe AES-256-CBC -certpbe AES-256-CBC -passout "pass:$PASS" 2>&1 | WriteAndLog
echo "Adding $ALIAS to the $KEYSTORE" | WriteAndLog
# Use the p12 file to import into a java keystore via keytool
keytool -importkeystore -srckeystore "tmpkey.p12" -destkeystore $KEYSTORE -srcstoretype pkcs12 -srcstorepass $PASS -deststoretype jks -deststorepass $PASS -noprompt -alias 1 -destalias "$ALIAS" 2>&1 | WriteAndLog
echo "Adding $ALIAS to the $TRUSTSTORE" | WriteAndLog
# Import the cert into a java trust store via keytool
keytool -import -keystore $TRUSTSTORE -storepass $PASS -file "$CERT_PATH.pem" -noprompt -alias "$ALIAS" 2>&1 | WriteAndLog
# Remove the temp p1 file.
echo "Cleaning up after storing $ALIAS" | WriteAndLog
rm "tmpkey.p12"
}
# Function to create an Intermediate Key, CSR, and Certificate
# PARMS:
# 1. Cert Type String
# 2. Issuer Key File Name
# 3. Subject Distinguished Name String
Function create_cert () {
param (
[string]$CERT_PATH = $null,
[string]$ISSUER = $null,
[string]$SUBJ_DN = $null,
[string]$EXTENSION = $null
)
$ISSUER_KEY="$ISSUER.key"
$ISSUER_CERT="$ISSUER.pem"
$ALIAS=[System.IO.Path]::GetFileName($CERT_PATH) # Use filename without path as an alias
echo "Creating key pair and CSR with DN=`"$SUBJ_DN`"." | WriteAndLog
echo " Key pair will be saved at location $CERT_PATH\" | WriteAndLog
echo " Key will use $ASYM_ALG $ASYM_SIZE and HASH Alg $HASH_ALG" | WriteAndLog
echo " Certificate will be issued by $ISSUER_CERT and its key $ISSUER_KEY." | WriteAndLog
echo " Key objects will use the alias `"$ALIAS`" in trust stores." | WriteAndLog
# Database doesnt support encypted key so create DB without passwords
if ("$SUBJ_DN" -match "DB") {
echo "This key is intended for use with the database." | WriteAndLog
if ("$ASYM_ALG" -eq "rsa") {
openssl genrsa -out "$CERT_PATH.key" "$ASYM_SIZE" 2>&1 | WriteAndLog
openssl req -new -key "$CERT_PATH.key" -out "$CERT_PATH.csr" -subj "$SUBJ_DN" 2>&1 | WriteAndLog
} else {
openssl ecparam -genkey -name "$ECC_NAME" -out "$CERT_PATH.key" 2>&1 | WriteAndLog
openssl req -new -key "$CERT_PATH.key" -out "$CERT_PATH.csr" -$HASH_ALG -subj "$SUBJ_DN" 2>&1 | WriteAndLog
}
} else {
if ("$ASYM_ALG" -eq "rsa") {
openssl req -newkey rsa:"$ASYM_SIZE" -keyout "$CERT_PATH.key" -out "$CERT_PATH.csr" -subj "$SUBJ_DN" -passout "pass:$PASS" 2>&1 | WriteAndLog
} else {
openssl genpkey -algorithm "EC" -pkeyopt ec_paramgen_curve:P-521 -aes256 --pass "pass:$PASS" -out "$CERT_PATH.key" 2>&1 | WriteAndLog
openssl req -new -key "$CERT_PATH.key" -passin "pass:$PASS" -out "$CERT_PATH.csr" -$HASH_ALG -subj "$SUBJ_DN" 2>&1 | WriteAndLog
}
}
echo "Sending CSR to the CA." | WriteAndLog
pushd "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" | WriteAndLog
openssl ca -config ca.conf -keyfile "$ISSUER_KEY" -md $HASH_ALG -cert "$ISSUER_CERT" -extensions "$EXTENSION" -out "$CERT_PATH.pem" -in "$CERT_PATH.csr" -passin "pass:$PASS" -batch -notext 2>&1 | WriteAndLog
popd | WriteAndLog
# Increment the cert serial number
$SERIAL=(Get-Content "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\serial.txt")
echo "Cert Serial Number = $SERIAL" | WriteAndLog
echo "Exporting key and certificate to PKCS12." | WriteAndLog
# Add the cert and key to the key store. make a p12 file to import into te keystore
openssl pkcs12 -export -in "$CERT_PATH.pem" -inkey "$CERT_PATH.key" -out "tmpkey.p12" -passin "pass:$PASS" -macalg SHA256 -keypbe AES-256-CBC -certpbe AES-256-CBC -passout "pass:$PASS" 2>&1 | WriteAndLog
echo "Adding $ALIAS to $KEYSTORE" | WriteAndLog
# Use the p12 file to import into a java keystore via keytool
keytool -importkeystore -srckeystore "tmpkey.p12" -destkeystore $KEYSTORE -srcstoretype pkcs12 -srcstorepass $PASS -deststoretype jks -deststorepass $PASS -noprompt -alias 1 -destalias "$ALIAS" 2>&1 | WriteAndLog
# Import the cert into a java trust store via keytool
echo "Adding $ALIAS to $TRUSTSTORE" | WriteAndLog
keytool -import -keystore $TRUSTSTORE -storepass $PASS -file "$CERT_PATH.pem" -noprompt -alias "$ALIAS" 2>&1 | WriteAndLog
echo "Cleaning up after storing $ALIAS" | WriteAndLog
# Remove the temp p12 file.
rm "tmpkey.p12"# remove csr file
rm "$CERT_PATH.csr"
}
Function create_cert_chain () {
# Create an intermediate CA, Sign with Root CA
create_cert "$PKI_INT" "$PKI_ROOT" "$INT_DN" "ca_extensions"
# Create a Leaf CA (CA1), Sign with intermediate CA
create_cert "$PKI_CA1" "$PKI_INT" ("$LEAF_DN"+1) "ca_extensions"
# Create a Leaf CA (CA2), Sign with intermediate CA
create_cert "$PKI_CA2" "$PKI_INT" ("$LEAF_DN"+2) "ca_extensions"
# Create a Leaf CA (CA3), Sign with intermediate CA
create_cert "$PKI_CA3" "$PKI_INT" ("$LEAF_DN"+3) "ca_extensions"
# Create a RIM Signer
create_cert "$RIM_SIGNER" "$PKI_CA2" "$SIGNER_DN" "signer_extensions"
# Create a ACA Sever Cert for TLS use
create_cert "$TLS_SERVER" "$PKI_CA3" "$TLS_DN" "server_extensions"
# Create a DB Sever Cert for TLS use
create_cert "$DB_SERVER" "$PKI_CA3" "$DB_SRV_DN" "server_extensions"
# Create a ACA Sever Cert for TLS use
create_cert "$DB_CLIENT" "$PKI_CA3" "$DB_CLIENT_DN" "server_extensions"
echo "Creating concatenated PEM file." | WriteAndLog
# Create Cert trust store by adding the Intermediate and root certs
cat "$PKI_CA1.pem", "$PKI_CA2.pem", "$PKI_CA3.pem", "$PKI_INT.pem", "$PKI_ROOT.pem" > "$TRUST_STORE_FILE"
echo "Verifying the concatenated PEM file works." | WriteAndLog
# Checking signer cert using trust store...
openssl verify -CAfile "$TRUST_STORE_FILE" "$RIM_SIGNER.pem" | WriteAndLog
echo "Creating a PKCS12 file for the database client." | WriteAndLog
# Make JKS files for the mysql DB connector. P12 first then JKS...
openssl pkcs12 -export -in "$DB_CLIENT.pem" -inkey "$DB_CLIENT.key" -macalg SHA256 -keypbe AES-256-CBC -certpbe AES-256-CBC -passin "pass:$PASS" -passout "pass:$PASS" -name "mysqlclientkey" -out "$DB_CLIENT.p12" 2>&1 | WriteAndLog
echo "Converting the database client PKCS12 file to JKS." | WriteAndLog
keytool -importkeystore -srckeystore "$DB_CLIENT.p12" -srcstoretype PKCS12 -srcstorepass $PASS -destkeystore "$DB_CLIENT.jks" -deststoretype jks -deststorepass $PASS 2>&1 | WriteAndLog
}
if ("$ASYM_ALG" -eq "rsa") {
# Create Root CA key pair and self signed cert
echo "Generating RSA Root CA ...." | WriteAndLog
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -aes256 --pass "pass:$PASS" -out "$PKI_ROOT.key" 2>&1 | WriteAndLog
# Create a self signed CA certificate
pushd "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" | WriteAndLog
openssl req -new -config ca.conf -x509 -days 3650 -key "$PKI_ROOT.key" -subj "$ROOT_DN" -extensions ca_extensions -out "$PKI_ROOT.pem" -passin "pass:$PASS" 2>&1 | WriteAndLog
popd | WriteAndLog
# Add the CA root cert to the Trust and Key stores
add_to_stores "$PKI_ROOT"
# Create an intermediate CA, 2 Leaf CAs, and Signer Certs
create_cert_chain
}
if ("$ASYM_ALG" -eq "ecc") {
# Create Root CA key pair and self signed cert
echo "Generating Ecc Root CA ...." | WriteAndLog
openssl genpkey -algorithm "EC" -pkeyopt ec_paramgen_curve:P-521 -aes256 --pass "pass:$PASS" -out "$PKI_ROOT.key" 2>&1 | WriteAndLog
# Create a self signed CA certificate
pushd "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" | WriteAndLog
openssl req -new -config ca.conf -x509 -days 3650 -key "$PKI_ROOT.key" -subj "$ROOT_DN" -extensions ca_extensions -out "$PKI_ROOT.pem" -passin "pass:$PASS" 2>&1 | WriteAndLog
popd | WriteAndLog
# Add the CA root cert to the Trust and Key stores
add_to_stores "$PKI_ROOT"
# Create an intermediate CA, 2 Leaf CAs, and Signer Certs
create_cert_chain
}

View File

@ -0,0 +1,78 @@
#!/bin/bash
############################################################################################
# Creates 2 Certificate Chains for the ACA:
# 1 RSA 3K SHA 384
# 2 ECC 512 SHA 384
#
############################################################################################
param (
[string]$LOG_FILE = $null,
[string]$PKI_PASS = $null,
[switch]$UNATTENDED = $false
)
$APP_HOME=(Split-Path -parent $PSCommandPath)
$ACA_COMMON_SCRIPT=(Join-Path "$APP_HOME" .. aca aca_common.ps1)
# Load other scripts
. $ACA_COMMON_SCRIPT
# Read aca.properties
read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
# Read spring application.properties
read_spring_properties $global:HIRS_DATA_SPRING_PROP_FILE
# Parameter check
if ($LOG_FILE) {
touch $LOG_FILE
$global:LOG_FILE=$LOG_FILE
} else {
set_up_log
}
if (!$PKI_PASS) {
if ($Env:HIRS_PKI_PWD) {
$PKI_PASS=$Env:HIRS_PKI_PWD
} else {
$PKI_PASS=(create_random)
echo "Using randomly generated password for the PKI key password" | WriteAndLog
}
}
mkdir -p $global:HIRS_CONF_DIR 2>&1 > $null
echo "APP_HOME is $APP_HOME" | WriteAndLog
# Check for sudo or root user
if(!(New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent())
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
echo "This script requires root. Please run as root" | WriteAndLog
exit 1
}
# Create Cert Chains
if (![System.IO.Directory]::Exists($global:HIRS_DATA_CERTIFICATES_DIR)) {
if ([System.IO.Directory]::Exists($global:HIRS_REL_WIN_PKI_HOME)) {
$PKI_SETUP_DIR=$global:HIRS_REL_WIN_PKI_HOME
} else {
$PKI_SETUP_DIR=$APP_HOME
}
echo "PKI_SETUP_DIR is $PKI_SETUP_DIR" | WriteAndLog
mkdir -F -p $global:HIRS_DATA_CERTIFICATES_DIR 2>&1 > $null
cp $PKI_SETUP_DIR/ca.conf $global:HIRS_DATA_CERTIFICATES_DIR
pwsh -ExecutionPolicy Bypass $PKI_SETUP_DIR/pki_chain_gen.ps1 "HIRS" "rsa" "3072" "sha384" "$PKI_PASS" "$global:LOG_FILE"
pwsh -ExecutionPolicy Bypass $PKI_SETUP_DIR/pki_chain_gen.ps1 "HIRS" "ecc" "512" "sha384" "$PKI_PASS" "$global:LOG_FILE"
# Save the password to the ACA properties file.
add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"hirs_pki_password=$PKI_PASS"
# Save connector information to the application properties file.
add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"server.ssl.key-store-password=$PKI_PASS"
add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"server.ssl.trust-store-password=$PKI_PASS"
} else {
echo "$global:HIRS_DATA_CERTIFICATES_DIR exists, skipping" | WriteAndLog
}