genintcerts.sh 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. #!/bin/sh
  2. # Script for generating RSA and ECC Intermediate CA and server/client certs based on it.
  3. # Result is chains that looks like:
  4. # RSA Server
  5. # ROOT: ./certs/ca-cert.pem
  6. # C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.wolfssl.com/emailAddress=info@wolfssl.com)
  7. # INTERMEDIATE: ./certs/intermediate/ca-int-cert.pem
  8. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate CA/emailAddress=info@wolfssl.com
  9. # INTERMEDIATE2: ./certs/intermediate/ca-int2-cert.pem
  10. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate2 CA/emailAddress=info@wolfssl.com
  11. # SERVER: ./certs/intermediate/server-int-cert.pem
  12. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Server Chain/emailAddress=info@wolfssl.com
  13. # RSA Client
  14. # ROOT: ./certs/ca-cert.pem
  15. # C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.wolfssl.com/emailAddress=info@wolfssl.com)
  16. # INTERMEDIATE: ./certs/intermediate/ca-int-cert.pem
  17. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate CA/emailAddress=info@wolfssl.com
  18. # INTERMEDIATE: ./certs/intermediate/ca-int2-cert.pem
  19. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate2 CA/emailAddress=info@wolfssl.com
  20. # CLIENT: ./certs/intermediate/client-int-cert.pem
  21. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Client Chain/emailAddress=info@wolfssl.com
  22. # ECC Server
  23. # ROOT: ./certs/ca-ecc-cert.pem
  24. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=www.wolfssl.com/emailAddress=info@wolfssl.com
  25. # INTERMEDIATE: ./certs/intermediate/ca-int-ecc-cert.pem
  26. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate CA ECC/emailAddress=info@wolfssl.com
  27. # INTERMEDIATE2: ./certs/intermediate/ca-int-ecc-cert.pem
  28. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate2 CA ECC/emailAddress=info@wolfssl.com
  29. # SERVER: ./certs/intermediate/server-int-ecc-cert.pem
  30. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Server Chain ECC/emailAddress=info@wolfssl.com
  31. # ECC Client
  32. # ROOT: ./certs/ca-ecc-cert.pem
  33. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=www.wolfssl.com/emailAddress=info@wolfssl.com
  34. # INTERMEDIATE: ./certs/intermediate/ca-int-ecc-cert.pem
  35. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate CA ECC/emailAddress=info@wolfssl.com
  36. # INTERMEDIATE2: ./certs/intermediate/ca-int2-ecc-cert.pem
  37. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate2 CA ECC/emailAddress=info@wolfssl.com
  38. # CLIENT: ./certs/intermediate/client-int-ecc-cert.pem
  39. # C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Client Chain ECC/emailAddress=info@wolfssl.com
  40. # Run from wolfssl-root as `./certs/intermediate/genintcerts.sh`
  41. # To cleanup temp files use `./certs/intermediate/genintcerts.sh clean`
  42. # To cleanup all files use `./certs/intermediate/genintcerts.sh cleanall`
  43. dir="."
  44. cleanup_files(){
  45. rm -f ./certs/intermediate/index.*
  46. rm -f ./certs/intermediate/*.old
  47. rm -f ./certs/intermediate/serial
  48. rm -f ./certs/intermediate/crlnumber
  49. rm -f ./certs/intermediate/*.cnf
  50. rm -rf ./certs/intermediate/new_certs
  51. exit 0
  52. }
  53. check_result() {
  54. if [ $1 -ne 0 ]; then
  55. echo "Step Failed, Abort"
  56. exit 1
  57. else
  58. echo "Step Succeeded!"
  59. fi
  60. }
  61. # Args: 1=CnfFile, 2=Key, 3=Cert
  62. create_ca_config() {
  63. echo "# Generated openssl conf" > "$1"
  64. echo "[ ca ]" >> "$1"
  65. echo "default_ca = CA_default" >> "$1"
  66. echo "" >> "$1"
  67. echo "[ CA_default ]" >> "$1"
  68. echo "certs = $dir/certs/intermediate" >> "$1"
  69. echo "new_certs_dir = $dir/certs/intermediate/new_certs">> "$1"
  70. echo "database = $dir/certs/intermediate/index.txt">> "$1"
  71. echo "serial = $dir/certs/intermediate/serial" >> "$1"
  72. echo "RANDFILE = $dir/private/.rand" >> "$1"
  73. echo "" >> "$1"
  74. echo "private_key = $dir/$2" >> "$1"
  75. echo "certificate = $dir/$3" >> "$1"
  76. echo "" >> "$1"
  77. echo "crlnumber = $dir/certs/intermediate/crlnumber">> "$1"
  78. echo "crl_extensions = crl_ext" >> "$1"
  79. echo "default_crl_days = 1000" >> "$1"
  80. echo "default_md = sha256" >> "$1"
  81. echo "" >> "$1"
  82. echo "name_opt = ca_default" >> "$1"
  83. echo "cert_opt = ca_default" >> "$1"
  84. echo "default_days = 3650" >> "$1"
  85. echo "preserve = no" >> "$1"
  86. echo "policy = policy_loose" >> "$1"
  87. echo "" >> "$1"
  88. echo "[ policy_strict ]" >> "$1"
  89. echo "countryName = match" >> "$1"
  90. echo "stateOrProvinceName = match" >> "$1"
  91. echo "organizationName = match" >> "$1"
  92. echo "organizationalUnitName = optional" >> "$1"
  93. echo "commonName = supplied" >> "$1"
  94. echo "emailAddress = optional" >> "$1"
  95. echo "" >> "$1"
  96. echo "[ policy_loose ]" >> "$1"
  97. echo "countryName = optional" >> "$1"
  98. echo "stateOrProvinceName = optional" >> "$1"
  99. echo "localityName = optional" >> "$1"
  100. echo "organizationName = optional" >> "$1"
  101. echo "organizationalUnitName = optional" >> "$1"
  102. echo "commonName = supplied" >> "$1"
  103. echo "emailAddress = optional" >> "$1"
  104. echo "" >> "$1"
  105. echo "[ req ]" >> "$1"
  106. echo "default_bits = 2048" >> "$1"
  107. echo "distinguished_name = req_distinguished_name" >> "$1"
  108. echo "string_mask = utf8only" >> "$1"
  109. echo "default_md = sha256" >> "$1"
  110. echo "x509_extensions = v3_ca" >> "$1"
  111. echo "" >> "$1"
  112. echo "[ req_distinguished_name ]" >> "$1"
  113. echo "countryName = US" >> "$1"
  114. echo "stateOrProvinceName = Washington" >> "$1"
  115. echo "localityName = Seattle" >> "$1"
  116. echo "organizationName = wolfSSL" >> "$1"
  117. echo "organizationalUnitName = Development" >> "$1"
  118. echo "commonName = www.wolfssl.com" >> "$1"
  119. echo "emailAddress = info@wolfssl.com" >> "$1"
  120. echo "" >> "$1"
  121. echo "[ v3_ca ]" >> "$1"
  122. echo "subjectKeyIdentifier = hash" >> "$1"
  123. echo "authorityKeyIdentifier = keyid:always,issuer" >> "$1"
  124. echo "basicConstraints = critical, CA:true" >> "$1"
  125. echo "keyUsage = critical, digitalSignature, cRLSign, keyCertSign">> "$1"
  126. echo "" >> "$1"
  127. echo "[ v3_intermediate_ca ]" >> "$1"
  128. echo "subjectKeyIdentifier = hash" >> "$1"
  129. echo "authorityKeyIdentifier = keyid:always,issuer" >> "$1"
  130. echo "basicConstraints = critical, CA:true, pathlen:1" >> "$1"
  131. echo "keyUsage = critical, digitalSignature, cRLSign, keyCertSign">> "$1"
  132. echo "" >> "$1"
  133. echo "[ v3_intermediate2_ca ]" >> "$1"
  134. echo "subjectKeyIdentifier = hash" >> "$1"
  135. echo "authorityKeyIdentifier = keyid:always,issuer" >> "$1"
  136. echo "basicConstraints = critical, CA:true, pathlen:1" >> "$1"
  137. echo "keyUsage = critical, digitalSignature, cRLSign, keyCertSign">> "$1"
  138. echo "" >> "$1"
  139. echo "[ usr_cert ]" >> "$1"
  140. echo "basicConstraints = CA:FALSE" >> "$1"
  141. echo "nsCertType = client, email" >> "$1"
  142. echo "subjectKeyIdentifier = hash" >> "$1"
  143. echo "authorityKeyIdentifier = keyid,issuer" >> "$1"
  144. echo "keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment">> "$1"
  145. echo "extendedKeyUsage = clientAuth, emailProtection" >> "$1"
  146. echo "" >> "$1"
  147. echo "[ server_cert ]" >> "$1"
  148. echo "basicConstraints = CA:FALSE" >> "$1"
  149. echo "nsCertType = server" >> "$1"
  150. echo "subjectKeyIdentifier = hash" >> "$1"
  151. echo "authorityKeyIdentifier = keyid,issuer:always" >> "$1"
  152. echo "keyUsage = critical, digitalSignature, keyEncipherment, keyAgreement">> "$1"
  153. echo "extendedKeyUsage = serverAuth" >> "$1"
  154. echo "" >> "$1"
  155. echo "[ crl_ext ]" >> "$1"
  156. echo "authorityKeyIdentifier=keyid:always" >> "$1"
  157. }
  158. # Args: 1=reqcnf, 2=signcnf, 3=keyfile, 4=certfile, 5=ext, 6=subj, 7=days
  159. create_cert() {
  160. openssl req -config ./certs/intermediate/$1.cnf -new -sha256 \
  161. -key $3 \
  162. -out ./certs/intermediate/tmp.csr \
  163. -subj "/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=$6/emailAddress=info@wolfssl.com"
  164. check_result $?
  165. openssl ca -config ./certs/intermediate/$2.cnf -extensions $5 -days $7 -notext -md sha256 \
  166. -in ./certs/intermediate/tmp.csr -out ./certs/intermediate/$4.pem -batch
  167. check_result $?
  168. rm ./certs/intermediate/tmp.csr
  169. # Convert Cert to DER
  170. openssl x509 -in ./certs/intermediate/$4.pem -inform PEM -out ./certs/intermediate/$4.der -outform DER
  171. check_result $?
  172. # Add text to cert PEM file
  173. openssl x509 -in ./certs/intermediate/$4.pem -text > ./certs/intermediate/tmp.pem
  174. check_result $?
  175. mv ./certs/intermediate/tmp.pem ./certs/intermediate/$4.pem
  176. }
  177. if [ "$1" == "clean" ]; then
  178. echo "Cleaning temp files"
  179. cleanup_files
  180. fi
  181. if [ "$1" == "cleanall" ]; then
  182. echo "Cleaning all files"
  183. rm -f ./certs/intermediate/*.pem
  184. rm -f ./certs/intermediate/*.der
  185. rm -f ./certs/intermediate/*.csr
  186. cleanup_files
  187. fi
  188. # Make sure required CA files exist and are populated
  189. rm -f ./certs/intermediate/index.*
  190. touch ./certs/intermediate/index.txt
  191. if [ ! -f ./certs/intermediate/serial ]; then
  192. echo 1000 > ./certs/intermediate/serial
  193. fi
  194. if [ ! -f ./certs/intermediate/crlnumber ]; then
  195. echo 2000 > ./certs/intermediate/crlnumber
  196. fi
  197. if [ ! -d ./certs/intermediate/new_certs ]; then
  198. mkdir ./certs/intermediate/new_certs
  199. fi
  200. # RSA
  201. echo "Creating RSA CA configuration cnf files"
  202. create_ca_config ./certs/intermediate/wolfssl_root.cnf certs/ca-key.pem certs/ca-cert.pem
  203. create_ca_config ./certs/intermediate/wolfssl_int.cnf certs/intermediate/ca-int-key.pem certs/intermediate/ca-int-cert.pem
  204. create_ca_config ./certs/intermediate/wolfssl_int2.cnf certs/intermediate/ca-int2-key.pem certs/intermediate/ca-int2-cert.pem
  205. if [ ! -f ./certs/intermediate/ca-int-key.pem ]; then
  206. echo "Make Intermediate RSA CA Key"
  207. openssl genrsa -out ./certs/intermediate/ca-int-key.pem 2048
  208. check_result $?
  209. openssl rsa -in ./certs/intermediate/ca-int-key.pem -inform PEM -out ./certs/intermediate/ca-int-key.der -outform DER
  210. check_result $?
  211. fi
  212. if [ ! -f ./certs/intermediate/ca-int2-key.pem ]; then
  213. echo "Make Intermediate2 RSA CA Key"
  214. openssl genrsa -out ./certs/intermediate/ca-int2-key.pem 2048
  215. check_result $?
  216. openssl rsa -in ./certs/intermediate/ca-int2-key.pem -inform PEM -out ./certs/intermediate/ca-int2-key.der -outform DER
  217. check_result $?
  218. fi
  219. echo "Create RSA Intermediate CA signed by root"
  220. create_cert wolfssl_int wolfssl_root ./certs/intermediate/ca-int-key.pem ca-int-cert v3_intermediate_ca "wolfSSL Intermediate CA" 7300
  221. echo "Create RSA Intermediate2 CA signed by RSA Intermediate"
  222. create_cert wolfssl_int2 wolfssl_int ./certs/intermediate/ca-int2-key.pem ca-int2-cert v3_intermediate2_ca "wolfSSL Intermediate2 CA" 7300
  223. echo "Create RSA Server Certificate signed by intermediate2"
  224. create_cert wolfssl_int2 wolfssl_int2 ./certs/server-key.pem server-int-cert server_cert "wolfSSL Server Chain" 3650
  225. echo "Create RSA Client Certificate signed by intermediate2"
  226. create_cert wolfssl_int2 wolfssl_int2 ./certs/client-key.pem client-int-cert usr_cert "wolfSSL Client Chain" 3650
  227. echo "Generate CRLs for new certificates"
  228. openssl ca -config ./certs/intermediate/wolfssl_root.cnf -gencrl -crldays 1000 -out ./certs/crl/ca-int.pem -keyfile ./certs/intermediate/ca-int-key.pem -cert ./certs/intermediate/ca-int-cert.pem
  229. check_result $?
  230. openssl ca -config ./certs/intermediate/wolfssl_int.cnf -gencrl -crldays 1000 -out ./certs/crl/ca-int2.pem -keyfile ./certs/intermediate/ca-int2-key.pem -cert ./certs/intermediate/ca-int2-cert.pem
  231. check_result $?
  232. openssl ca -config ./certs/intermediate/wolfssl_int2.cnf -gencrl -crldays 1000 -out ./certs/crl/server-int.pem -keyfile ./certs/server-key.pem -cert ./certs/intermediate/server-int-cert.pem
  233. check_result $?
  234. openssl ca -config ./certs/intermediate/wolfssl_int2.cnf -gencrl -crldays 1000 -out ./certs/crl/client-int.pem -keyfile ./certs/client-key.pem -cert ./certs/intermediate/client-int-cert.pem
  235. check_result $?
  236. echo "Assemble test chains - peer first, then intermediate2, then intermediate"
  237. openssl x509 -in ./certs/intermediate/server-int-cert.pem > ./certs/intermediate/server-chain.pem
  238. openssl x509 -in ./certs/intermediate/ca-int2-cert.pem >> ./certs/intermediate/server-chain.pem
  239. openssl x509 -in ./certs/intermediate/ca-int-cert.pem >> ./certs/intermediate/server-chain.pem
  240. cat ./certs/intermediate/server-int-cert.der ./certs/intermediate/ca-int2-cert.der ./certs/intermediate/ca-int-cert.der > ./certs/intermediate/server-chain.der
  241. openssl x509 -in ./certs/intermediate/client-int-cert.pem > ./certs/intermediate/client-chain.pem
  242. openssl x509 -in ./certs/intermediate/ca-int2-cert.pem >> ./certs/intermediate/client-chain.pem
  243. openssl x509 -in ./certs/intermediate/ca-int-cert.pem >> ./certs/intermediate/client-chain.pem
  244. cat ./certs/intermediate/client-int-cert.der ./certs/intermediate/ca-int2-cert.der ./certs/intermediate/ca-int-cert.der > ./certs/intermediate/client-chain.der
  245. echo "Assemble cert chain with extra cert for testing alternate chains"
  246. cp ./certs/intermediate/server-chain.pem ./certs/intermediate/server-chain-alt.pem
  247. cp ./certs/intermediate/client-chain.pem ./certs/intermediate/client-chain-alt.pem
  248. openssl x509 -in ./certs/external/ca-google-root.pem >> ./certs/intermediate/server-chain-alt.pem
  249. openssl x509 -in ./certs/external/ca-google-root.pem >> ./certs/intermediate/client-chain-alt.pem
  250. # ECC
  251. echo "Creating ECC CA configuration cnf files"
  252. create_ca_config ./certs/intermediate/wolfssl_root_ecc.cnf certs/ca-ecc-key.pem certs/ca-ecc-cert.pem
  253. create_ca_config ./certs/intermediate/wolfssl_int_ecc.cnf certs/intermediate/ca-int-ecc-key.pem certs/intermediate/ca-int-ecc-cert.pem
  254. create_ca_config ./certs/intermediate/wolfssl_int2_ecc.cnf certs/intermediate/ca-int2-ecc-key.pem certs/intermediate/ca-int2-ecc-cert.pem
  255. if [ ! -f ./certs/intermediate/ca-int-ecc-key.pem ]; then
  256. echo "Make Intermediate ECC CA Key"
  257. openssl ecparam -name prime256v1 -genkey -noout -out ./certs/intermediate/ca-int-ecc-key.pem
  258. check_result $?
  259. openssl ec -in ./certs/intermediate/ca-int-ecc-key.pem -inform PEM -out ./certs/intermediate/ca-int-ecc-key.der -outform DER
  260. check_result $?
  261. fi
  262. if [ ! -f ./certs/intermediate/ca-int2-ecc-key.pem ]; then
  263. echo "Make Intermediate2 ECC CA Key"
  264. openssl ecparam -name prime256v1 -genkey -noout -out ./certs/intermediate/ca-int2-ecc-key.pem
  265. check_result $?
  266. openssl ec -in ./certs/intermediate/ca-int2-ecc-key.pem -inform PEM -out ./certs/intermediate/ca-int2-ecc-key.der -outform DER
  267. check_result $?
  268. fi
  269. echo "Create ECC Intermediate CA signed by root"
  270. create_cert wolfssl_int_ecc wolfssl_root_ecc ./certs/intermediate/ca-int-ecc-key.pem ca-int-ecc-cert v3_intermediate_ca "wolfSSL Intermediate CA ECC" 7300
  271. echo "Create ECC Intermediate2 CA signed by Intermediate"
  272. create_cert wolfssl_int2_ecc wolfssl_int_ecc ./certs/intermediate/ca-int2-ecc-key.pem ca-int2-ecc-cert v3_intermediate2_ca "wolfSSL Intermediate2 CA ECC" 7300
  273. echo "Create ECC Server Certificate signed by intermediate2"
  274. create_cert wolfssl_int2_ecc wolfssl_int2_ecc ./certs/ecc-key.pem server-int-ecc-cert server_cert "wolfSSL Server Chain ECC" 3650
  275. echo "Create ECC Client Certificate signed by intermediate2"
  276. create_cert wolfssl_int2_ecc wolfssl_int2_ecc ./certs/ecc-client-key.pem client-int-ecc-cert usr_cert "wolfSSL Client Chain ECC" 3650
  277. echo "Generate CRLs for new certificates"
  278. openssl ca -config ./certs/intermediate/wolfssl_root_ecc.cnf -gencrl -crldays 1000 -out ./certs/crl/ca-int-ecc.pem -keyfile ./certs/intermediate/ca-int-ecc-key.pem -cert ./certs/intermediate/ca-int-ecc-cert.pem
  279. check_result $?
  280. openssl ca -config ./certs/intermediate/wolfssl_int_ecc.cnf -gencrl -crldays 1000 -out ./certs/crl/ca-int2-ecc.pem -keyfile ./certs/intermediate/ca-int2-ecc-key.pem -cert ./certs/intermediate/ca-int2-ecc-cert.pem
  281. check_result $?
  282. openssl ca -config ./certs/intermediate/wolfssl_int2_ecc.cnf -gencrl -crldays 1000 -out ./certs/crl/server-int-ecc.pem -keyfile ./certs/ecc-key.pem -cert ./certs/intermediate/server-int-ecc-cert.pem
  283. check_result $?
  284. openssl ca -config ./certs/intermediate/wolfssl_int2_ecc.cnf -gencrl -crldays 1000 -out ./certs/crl/client-int-ecc.pem -keyfile ./certs/ecc-client-key.pem -cert ./certs/intermediate/client-int-ecc-cert.pem
  285. check_result $?
  286. echo "Assemble test chains - peer first, then intermediate2, then intermediate"
  287. openssl x509 -in ./certs/intermediate/server-int-ecc-cert.pem > ./certs/intermediate/server-chain-ecc.pem
  288. openssl x509 -in ./certs/intermediate/ca-int2-ecc-cert.pem >> ./certs/intermediate/server-chain-ecc.pem
  289. openssl x509 -in ./certs/intermediate/ca-int-ecc-cert.pem >> ./certs/intermediate/server-chain-ecc.pem
  290. cat ./certs/intermediate/server-int-ecc-cert.der ./certs/intermediate/ca-int2-ecc-cert.der ./certs/intermediate/ca-int-ecc-cert.der > ./certs/intermediate/server-chain-ecc.der
  291. openssl x509 -in ./certs/intermediate/client-int-ecc-cert.pem > ./certs/intermediate/client-chain-ecc.pem
  292. openssl x509 -in ./certs/intermediate/ca-int2-ecc-cert.pem >> ./certs/intermediate/client-chain-ecc.pem
  293. openssl x509 -in ./certs/intermediate/ca-int-ecc-cert.pem >> ./certs/intermediate/client-chain-ecc.pem
  294. cat ./certs/intermediate/client-int-ecc-cert.der ./certs/intermediate/ca-int2-ecc-cert.der ./certs/intermediate/ca-int-ecc-cert.der > ./certs/intermediate/client-chain-ecc.der
  295. echo "Assemble cert chain with extra untrusted cert for testing alternate chains"
  296. cp ./certs/intermediate/server-chain-ecc.pem ./certs/intermediate/server-chain-alt-ecc.pem
  297. cp ./certs/intermediate/client-chain-ecc.pem ./certs/intermediate/client-chain-alt-ecc.pem
  298. openssl x509 -in ./certs/external/ca-google-root.pem >> ./certs/intermediate/server-chain-alt-ecc.pem
  299. openssl x509 -in ./certs/external/ca-google-root.pem >> ./certs/intermediate/client-chain-alt-ecc.pem