#! /usr/bin/env bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and

# make-ssl-multicert: generate arbitrary numbers of SSL certificates
# Generate up to $COUNT SSL certificates and the corresponding ssl_multicert.config

OPENSSL=${OPENSSL:-openssl}
COUNT=${COUNT:-100001}
NPROCS=${NPROC:-$(getconf _NPROCESSORS_ONLN)}

makecert() {
  name=$1

  $OPENSSL genrsa -out ${name}.key 2048
  $OPENSSL req -new -key ${name}.key -out ${name}.csr \
    -subj /C=US/ST=CA/L=Norm/O=TrafficServer/OU=Test/CN=${name}.com
  $OPENSSL x509 -req -days 365 \
    -in ${name}.csr -signkey ${name}.key -out ${name}.crt
  cat ${name}.crt ${name}.key > ${name}.pem
  rm -rf ${name}.csr ${name}.key ${name}.crt
}

for (( i = 0 ; i < $COUNT ; i += $NPROCS )); do

  for ((j = i; j < (i + $NPROCS) && j < $COUNT; j++ )) ; do
    makecert "test${j}" &
  done

  wait

  for ((j = i; j < (i + $NPROCS) && j < $COUNT; j++ )) ; do
    echo ssl_cert_name=test$j.pem
  done >> ssl_multicert.config
done
