<?xml version='1.0' encoding='utf-8'?>
<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes"?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<?rfc iprnotified="no" ?>
<?rfc strict="no" ?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" consensus="true" docName="draft-moskowitz-ec-pki-02"
	category="info" ipr="trust200902" obsoletes="" submissionType="IETF" tocDepth="3"
	xml:lang="en" tocInclude="true" symRefs="true" sortRefs="true" version="3">
 <front> <title abbrev="EC PKI Guide">Guide for building an EC PKI</title>
    <seriesInfo name="Internet-Draft" value="draft-moskowitz-ec-pki-02"/>
	<author fullname="Robert Moskowitz" initials="R." surname="Moskowitz" >
        <organization>HTT Consulting</organization>
        <address>
        <postal>
          <street> </street>
          <city>Oak Park</city>
          <region>MI</region>
          <code>48237</code>
        </postal>
        <email>rgm@labs.htt-consult.com</email>
        </address>
	</author>
	<author fullname="Henk Birkholz" initials="H." surname="Birkholz">
      <organization>Fraunhofer SIT</organization>
      <address>
        <postal>
          <street>Rheinstrasse 75</street>
          <city>Darmstadt</city>
          <code>64295</code>
          <country>Germany</country>
        </postal>
        <email>henk.birkholz@sit.fraunhofer.de</email>
      </address>
	</author>
	<author fullname="Michael C. Richardson" initials="M." surname="Richardson">
      <organization abbrev="Sandelman">Sandelman Software Works</organization>
      <address>
        <email>mcr+ietf@sandelman.ca</email>
        <uri>http://www.sandelman.ca/</uri>
      </address>
	</author>
<date year="2024"/>
   <area>Security Area</area>
   <workgroup>wg TBD</workgroup>
    <keyword>RFC</keyword>
     <keyword>Request for Comments</keyword>
     <keyword>I-D</keyword>
     <keyword>Internet-Draft</keyword>
     <keyword>PKI</keyword>
     <keyword>ECDSA</keyword>
     <keyword>EdDSA</keyword>
     <keyword>802.1AR</keyword>

<abstract>
<t>
		This memo provides a guide for building a PKI (Public Key 
		Infrastructure) of EC certificates using openSSL.  Certificates 
		in this guide can use either ECDSA or EdDSA.  Along with common 
		End Entity certificates, this guide provides instructions for 
		creating IEEE 802.1AR iDevID Secure Device certificates.
</t>
</abstract>
</front>
<middle>
<section anchor="intro" title="Introduction">
<t>
	The IETF has a plethora of security solutions targeted at IoT.  Yet 
	all too many IoT products are tested and deployed with no or 
	improperly configured security.  In particular resource constrained 
	IoT devices and non-IP IoT networks have not been well served in 
	the IETF.
</t>
<t>
	Additionally, more IETF (e.g. DOTS, NETCONF) efforts are requiring 
	secure identities, but are vague on the nature of these identities 
	other than to recommend use of X.509 digital certificates and 
	perhaps TLS.
</t>
<t>
	This effort provides the steps, using the openSSL application, to 
	create such a PKI of ECDSA <xref 
	target="DOI_10.6028_NIST.FIPS.186-5" format="default"/>, ED25519, 
	or ED448 (<xref target="RFC8032"/> and <xref 
	target="DOI_10.6028_NIST.FIPS.186-5" format="default"/>) 
	certificates.  The goal is that any developer or tester can follow 
	these steps, create the basic objects needed and establish the 
	validity of the standard/program design.  This guide can even be 
	used to create a production PKI, though additional steps need to be 
	taken. This could be very useful to a small vendor needing to 
	include <xref target="DOI_10.1109_IEEESTD.2018.8423794" 
	format="default">802.1AR</xref> that references <xref 
	target="RFC4108" format="default"/> iDevIDs in their product (Note: 
	EdDSA certificates are not supported in 802.1AR-2018; this is for 
	future work).
</t>
<t>
	This guide was originally developed with openSSL 1.1.1; it is 
	updated using openSSL 3.0.9 on Fedora 38 and creates PEM-based 
	certificates.  It closely follows <xref 
	target="I-D.moskowitz-ecdsa-pki"/>.  Current updates follow some 
	lessons learned in developing <xref 
	target="I-D.moskowitz-drip-dki"/>
</t>
<t>
	Previous versions had multiple openssl config files.  This version 
	has a single config file to support all the openssl commands used 
	herein.
</t>
</section>
<section anchor="terms" title="Terms and Definitions">
<section title="Requirements Terminology">
<t>
		The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
		NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED",
		"MAY", and "OPTIONAL" in this document are to be interpreted as
		described in BCP 14 <xref target="RFC2119" /> <xref
		target="RFC8174" /> when, and only when, they appear in all
		capitals, as shown here.
</t>
</section>
<section title="Notations">
 <t> This section will contain notations </t>
</section>
<section title="Definitions">
        <t>
                There are no draft specific definitions at this time
        </t>
</section>
</section>
<section anchor="ECDSA" title="Comparing ECDSA and EdDSA certificates">
<t>
		There are two differences between ECDSA and EdDSA certificates
		that impact the use of openSSL.  There are no options with
		EdDSA, and thus the pkeyopt variable is not used.
</t>
<t>
		Likewise there are no hash options.  The hashes used by EdDSA 
		are preset and not selectable.  As such, none of the hash 
		options should be needed.
</t>
<t>
		It should be noted here that ED25519 certificates can be ~100 
		bytes smaller than corresponding ECDSA certificates not using 
		ECDSA point-compression.  This size difference may be critical 
		in some devices and communication technologies.  ED448 
		certificates are similar in size with ECDSA p256 certificates 
		yet with a stronger security claim.
</t>
</section>
<section anchor="BasicPKI" title="The Basic PKI feature set">
<t>
	A basic PKI has two levels of hierarchy: Root and Intermediate. The
	Root level has the greatest risk, and is the least used.  It only
	signs the Intermediate level signing certificate.  As such, once
	the Root level is created and signs the Intermediate level
	certificate it can be locked up.  In fact, the Root level could
	exist completely on a uSD boot card for an ARM small computer like
	a RaspberryPi.  A copy of this card can be made and securely stored
	in a different location.
</t>
<t>
	The Root level contains the Root certificate private key, a 
	database of all root signed certificates, and the public root 
	certificate.  It can also contain the Intermediate level public 
	certificate and a Root level CRL.
</t>
<t>
	The Intermediate level contains the Intermediate certificate
	private key, the public certificate, a database of all its signed
	certificates, the certificate trust chain, and Intermediate level
	CRL.  It can also contain the End Entity public certificates.  The
	private key file needs to be keep securely.  For example as with
	the Root level, a mSD image for an ARM computer could contain the
	complete Intermediate level. This image is kept offline.  The End
	Entity CSR is copied to it, signed, and then the signed certificate
	and updated database are moved to the public image that lacks the
	private key.
</t>
<t>
	For a simple test PKI, all files can be kept on a single system
	that is managed by the tester.
</t>
<t>
	End Entities create a key pair and a Certificate Signing Request
	(CSR).  The private key is stored securely.  The CSR is delivered
	to the Intermediate level which uses the CSR to create the End
	Entity certificate.  This certificate, along with the trust chain
	back to the root, is then returned to the End Entity.
</t>
<t>
	There is more to a PKI, but this suffices for most development and
	testing needs.
</t>
</section>
<section anchor="RootLevel" title="Getting started and the Root level">
<t>
	This guide was originally developed on a Fedora 29-beta armv7hl 
	system (Cubieboard2 SoC).  It should work on most Linux and similar 
	systems that support openSSL 1.1.1.  Current work has been on with 
	openSSL 3.0.9 on Fedora 38.  All work was done in a terminal window 
	with extensive "cutting and pasting" from this draft guide into the 
	terminal window.  Users of this guide may find different behaviors 
	based on their system.
</t>
<t>
	The sourcecode blocks are now structured to work with Carsten 
	Bormann's kramdown-rfc-extract-sourcecode script.  At the time of 
	publication, this script was part of the gem kramdown-rfc 
	collection.
</t>
<t>
	Place the xml for this document into a directory and run:
</t>
<blockquote>
	kramdown-rfc-extract-sourcecode thisdraft.xml --dir=scriptdir
</blockquote>
<t>
	This will create all the scripts below into directory 
	scriptdir/bash and config files into scriptdir/conf.  Edit these to 
	suit your needs then proceed.
</t>
<section anchor="FirstStep" title="Setting up the Environment">
<t>
    The first step is to create the PKI environment.  Modify the
    variables in setup1.sh to suit your needs.
</t>
<sourcecode anchor="Fig_1" name="setup1.sh" type="bash">
<![CDATA[
export dir=/root/ca
export cadir=/root/ca
export format=pem
export algorithm=ed25519 # or ed448
# or for ECDSA with P-256:
# export algorithm="ec -pkeyopt ec_paramgen_curve:prime256v1"
mkdir $dir
cp scriptdir/conf/openssl.cnf $dir
cd $dir
mkdir certs crl csr newcerts private
chmod 700 private
touch index.txt
touch serial
sn=8

countryName="/C=US"
stateOrProvinceName="/ST=MI"
localityName="/L=Oak Park"
organizationName="/O=HTT Consulting"
#organizationalUnitName="/OU="
organizationalUnitName=
commonName="/CN=Root CA"
DN=$countryName$stateOrProvinceName$localityName
DN=$DN$organizationName$organizationalUnitName$commonName
echo $DN
export subjectAltName=email:postmaster@htt-consult.com
]]>
</sourcecode>
<artwork name="vars_1" type="null" align="left" alt="">
<![CDATA[


where:

dir       : Directory for certificate files

cadir     : Directory for Root certificate files

format    : File encoding:  PEM or DER
               At this time only PEM works

algorithm : EC algorithm used in certificates

sn        : Serial Number length in bytes
               For a public CA the range is 8 to 20

DN        : Distinguished Name
               Policy is LOOSE; Recommended at least
               providing Common Name
]]>
</artwork>
<t>
	The DN and SAN fields are examples.  Change them to appropriate
	values.  If you leave one blank, it will be left out of the
	Certificate.  "OU" above is an example of an empty DN object.
</t>
<blockquote>
	Make sure that $dir/openssl.cnf from the contents in <xref 
	target="configfile" /> exists.  setup1.sh should have copied it 
	into your CA directory.
</blockquote>
</section>
<section anchor="RootCert" title="Create the Root Certificate">
<t>
	Next is the rootcert.sh script with the openssl commands to create 
	the Root certificate keypair, and the Root certificate.  Included 
	are commands to view the file contents.
</t>
<t>
	Environment variables are used to provide considerable flexibility 
	in the certificate contents.  Many of these variables need to be 
	customized; sample values are provided.  Validity notBefore and 
	notAfter days variables are used, rather that life in days. This is 
	not supported in the standard self-sign root certificate creation, 
	so a "throw-away" self-signed certificate is created first which is 
	used to sign a certificate with the same key and proper validity 
	dates which is then the root certificate.
</t>
<t>
	It is not uncommon to get warning messages in "openssl ca" commands 
	on not including some value it expects.  For example a warning of 
	not having "default_days", as we are using actual validity dates.  
	These can be ignored.
</t>
<t>
	OpenSSL does not allow empty variables in the config file.  So in 
	the example below, certextkeyusage is empty.  There are a few 
	req_ext sections (e.g. req_ext_bkes, bke, bks, and bk) to cover the 
	more common sets of extensions used.  If a different set is needed, 
	add it to the config file.
</t>
<sourcecode anchor="Fig_2.1" name="rootcert.sh" type="bash">
<![CDATA[
# Create passworded keypair file

export encryptkey=""
#export encryptkey="-aes256"   # use to password protect private key

openssl genpkey $encryptkey -algorithm $algorithm\
    -outform $format -out $dir/private/ca.key.$format
# For ECDSA point-compression
#openssl ec -conv_form compressed \
#    -in $dir/private/ca.key.$format\
#    -out $dir/private/ca.key.$format
chmod 400 $dir/private/ca.key.$format
openssl pkey -inform $format -in $dir/private/ca.key.$format\
    -text -noout
]]>
</sourcecode>
<sourcecode anchor="Fig_2.2" name="rootcert.sh" type="bash">
<![CDATA[
# Create Self-signed Throw-away Certificate file

export signprv="ca"
export signcert="cabase"
export basicConstraints="critical, CA:true"
export certkeyusage="critical, keyCertSign"
export certextkeyusage=""
export hwType="place holder" # all ENV in config must
export hwSerialNum="place holder" #   be define
export startdate=20230801000000Z  # YYYYMMDDHHMMSSZ
export enddate=20430731000000Z  # YYYYMMDDHHMMSSZ

openssl req -config $dir/openssl.cnf\
     -set_serial 0x$(openssl rand -hex $sn)\
     -keyform $format -outform $format\
     -key $dir/private/ca.key.$format -subj "$DN"\
     -new -x509 -extensions v3_ca\
     -out $dir/certs/$signcert.cert.$format

openssl x509 -in $dir/certs/$signcert.cert.$format\
      -inform $format -text -noout
openssl x509 -purpose -inform $format\
     -in $dir/certs/$signcert.cert.$format -inform $format
]]>
</sourcecode>
<sourcecode anchor="Fig_2.3" name="rootcert.sh" type="bash">
<![CDATA[
# Create Self-signed Root Certificate file

openssl req -config $dir/openssl.cnf -reqexts req_ext_bk\
    -key $dir/private/ca.key.$format \
    -subj "$DN" -new -out $dir/csr/ca.csr.$format

openssl req -text -noout -verify\
    -in $dir/csr/ca.csr.$format

openssl rand -hex $sn > $dir/serial # hex 8 is minimum, 20 is maximum

openssl ca -config $dir/openssl.cnf\
    -extensions v3_ca -notext \
    -in $dir/csr/ca.csr.$format\
    -out $dir/certs/ca.cert.$format
chmod 444 $dir/certs/ca.cert.$format

openssl x509 -inform $format -in $dir/certs/ca.cert.$format\
     -text -noout
openssl x509 -purpose -inform $format\
     -in $dir/certs/ca.cert.$format -inform $format

openssl x509 -in $dir/certs/ca.cert.$format\
      -out $dir/certs/ca.cert.der -outform der
]]>
</sourcecode>
</section>
</section>
<section anchor="IntermediateLevel" title="The Intermediate level">
<section anchor="NextStep" title="Setting up the Intermediate Certificate Environment">
<t>
	The next part is to create the Intermediate PKI environment. Modify 
	the variables in intermediate_setup.sh to suit your needs.  In 
	particular, set the variables for CRL and/or OCSP support.
</t>
<sourcecode anchor="Fig_3.1" name="intermediate_setup.sh" type="bash">
<![CDATA[
export dir=$cadir/intermediate
mkdir $dir
cp openssl.cnf $dir
cd $dir
mkdir certs crl csr newcerts private
chmod 700 private
touch index.txt
sn=8 # hex 8 is minimum, 20 is maximum
echo 1000 > $dir/crlnumber
]]>
</sourcecode>
<sourcecode anchor="Fig_3.2" name="intermediate_setup.sh" type="bash">
<![CDATA[
# cd $dir
export crlDP=
# For CRL support use, uncomment these:
#crl=intermediate.crl.pem
#crlurl=www.htt-consult.com/pki/$crl
#export crlDP="URI:http://$crlurl"
export default_crl_days=30
export ocspIAI=
# For OCSP support use, uncomment these:
#ocspurl=ocsp.htt-consult.com
#export ocspIAI="OCSP;URI:http://$ocspurl"
export signprv="ca"
export signcert="ca"
export basicConstraints="critical, CA:true, pathlen:0"
export certkeyusage="critical, cRLSign, keyCertSign"
export certextkeyusage=""

commonName="/CN=Signing CA"
DN=$countryName$stateOrProvinceName$localityName$organizationName
DN=$DN$organizationalUnitName$commonName
echo $DN
]]>
</sourcecode>
<blockquote>
	The Intermediate level CA now uses the same openssl config file as 
	the root.  The intermediate_setup.sh should have copied it from the 
	main directory into the Intermediate.
</blockquote>
</section>
<section anchor="IntermediateCert" title="Create the Intermediate Certificate">
<t>
	Here are the openssl commands to create the Intermediate
	certificate keypair, Intermediate certificate signed request (CSR),
	and the Intermediate certificate.  Included are commands to view
	the file contents.
</t>
<sourcecode anchor="Fig_4.1" name="intermediate_cert.sh" type="bash">
<![CDATA[
# Create passworded keypair file

export encryptkey=""
#export encryptkey="-aes256"   # use to password protect private key

openssl genpkey $encryptkey -algorithm $algorithm\
    -outform $format -out $dir/private/intermediate.key.$format
# For ECDSA point-compression
#openssl ec -conv_form compressed \
#    -in $dir/private/intermediate.key.$format\
#    -out $dir/private/intermediate.key.$format
chmod 400 $dir/private/intermediate.key.$format
openssl pkey -inform $format\
    -in $dir/private/intermediate.key.$format -text -noout
]]>
</sourcecode>
<sourcecode anchor="Fig_4.2" name="intermediate_cert.sh" type="bash">
<![CDATA[
# Create the CSR

openssl req -config $cadir/openssl.cnf -reqexts req_ext_bk\
    -key $dir/private/intermediate.key.$format \
    -keyform $format -outform $format -subj "$DN" -new\
    -out $dir/csr/intermediate.csr.$format
openssl req -text -noout -verify -inform $format\
    -in $dir/csr/intermediate.csr.$format
]]>
</sourcecode>
<sourcecode anchor="Fig_4.3" name="intermediate_cert.sh" type="bash">
<![CDATA[
# Create Intermediate Certificate file

export startdate=230801000000Z  # YYMMDDHHMMSSZ
export enddate=20340731000000Z  # YYYYMMDDHHMMSSZ
openssl rand -hex $sn > $dir/serial # hex 8 is minimum, 20 is maximum
# Note 'openssl ca' does not support DER format

openssl ca -config $cadir/openssl.cnf\
    -extensions v3_intermediate_ca -notext \
    -in $dir/csr/intermediate.csr.$format\
    -out $dir/certs/intermediate.cert.pem

chmod 444 $dir/certs/intermediate.cert.$format

openssl verify -CAfile $cadir/certs/ca.cert.$format\
     $dir/certs/intermediate.cert.$format

openssl x509 -noout -text -in $dir/certs/intermediate.cert.$format
openssl x509 -in $dir/certs/intermediate.cert.$format\
      -out $dir/certs/intermediate.cert.der -outform der

# Create the certificate chain file

cat $dir/certs/intermediate.cert.$format\
   $cadir/certs/ca.cert.$format > $dir/certs/ca-chain.cert.$format
chmod 444 $dir/certs/ca-chain.cert.$format
]]>
</sourcecode>
</section>
<section anchor="ServerCert" title="Create a Server EE Certificate">
<t>
	Here are the openssl commands to create a Server End Entity
	certificate keypair, Server certificate signed request (CSR),
	and the Server certificate.  Included are commands to view
	the file contents.
</t>
<t>
	If EE certificates are created at a different time than the 
	Intermediate signing certificate, care needs to be taken that all 
	variables are properly reset.
</t>
<sourcecode anchor="Fig_5.1" name="end-server.sh" type="bash">
<![CDATA[
export cadir=$cadir/intermediate
commonName="/CN=Web Services"
DN=$countryName$stateOrProvinceName$localityName
DN=$DN$organizationName$organizationalUnitName$commonName
echo $DN
serverfqdn=www.example.com
emailaddr=postmaster@htt-consult.com
export subjectAltName="DNS:$serverfqdn, email:$emailaddr"
echo $subjectAltName
export signprv="intermediate"
export signcert="intermediate"
export basicConstraints="CA:FALSE"
export certkeyusage="critical, digitalSignature, keyEncipherment"
export certextkeyusage="serverAuth"
export encryptkey=""
#export encryptkey="-aes256"   # use to password protect private key

openssl genpkey $encryptkey -algorithm $algorithm\
    -out $dir/private/$serverfqdn.key.$format
# For ECDSA point-compression
#openssl ec -conv_form compressed \
#    -in $dir/private/$serverfqdn.key.$format\
#    -out $dir/private/$serverfqdn.key.$format
chmod 400 $dir/private/$serverfqdn.key.$format
openssl pkey -in $dir/private/$serverfqdn.key.$format -text -noout
openssl req -config $cadir/openssl.cnf -reqexts req_ext_bkes\
    -key $dir/private/$serverfqdn.key.$format \
    -subj "$DN" -new -out $dir/csr/$serverfqdn.csr.$format

openssl req -text -noout -verify -in $dir/csr/$serverfqdn.csr.$format
]]>
</sourcecode>
<sourcecode anchor="Fig_5.2" name="end-server.sh" type="bash">
<![CDATA[
export startdate=230801000000Z  # YYMMDDHHMMSSZ
export enddate=240731000000Z  # YYMMDDHHMMSSZ
openssl rand -hex $sn > $dir/serial # hex 8 is minimum, 20 is maximum
# Note 'openssl ca' does not support DER format
openssl ca -config $cadir/openssl.cnf\
    -extensions server_cert -notext \
    -in $dir/csr/$serverfqdn.csr.$format\
    -out $dir/certs/$serverfqdn.cert.$format
chmod 444 $dir/certs/$serverfqdn.cert.$format

openssl verify -CAfile $dir/certs/ca-chain.cert.$format\
     $dir/certs/$serverfqdn.cert.$format
openssl x509 -noout -text -in $dir/certs/$serverfqdn.cert.$format

openssl x509 -in $dir/certs/$serverfqdn.cert.$format\
      -out $dir/certs/$serverfqdn.cert.der -outform der
]]>
</sourcecode>
</section>
<section anchor="ClientCert" title="Create a Client EE Certificate">
<t>
	Here are the openssl commands to create a Client End Entity
	certificate keypair, Client certificate signed request (CSR),
	and the Client certificate.  Included are commands to view
	the file contents.
</t>
<t>
	For a Client certificate with "no" subject and only a 
	subjectAltName, set the variable DN to "/".  Also the 
	subjectAltName MUST be marked "critical".
</t>
<sourcecode anchor="Fig_6.1" name="end-client-dn.sh" type="bash">
<![CDATA[
commonName=
UserID="/UID=rgm"
DN=$countryName$stateOrProvinceName$localityName
DN=$DN$organizationName$organizationalUnitName$commonName$UserID
echo $DN
clientemail=rgm@example.com
export subjectAltName="email:$clientemail"
echo $subjectAltName
export basicConstraints="CA:FALSE"
export certkeyusage="critical, digitalSignature, keyEncipherment"
export certextkeyusage=""
export encryptkey=""
#export encryptkey="-aes256"   # use to password protect private key

openssl genpkey $encryptkey -algorithm $algorithm\
    -out $dir/private/$clientemail.key.$format
# For ECDSA point-compression
#openssl ec -conv_form compressed \
#    -in $dir/private/$clientemail.key.$format\
#    -out $dir/private/$clientemail.key.$format
chmod 400 $dir/private/$clientemail.key.$format
openssl pkey -in $dir/private/$clientemail.key.$format -text -noout
openssl req -config $dir/openssl.cnf -reqexts req_ext_bks\
    -key $dir/private/$clientemail.key.$format \
    -subj "$DN" -new -out $dir/csr/$clientemail.csr.$format

openssl req -text -noout -verify\
    -in $dir/csr/$clientemail.csr.$format
]]>
</sourcecode>
<sourcecode anchor="Fig_6.2" name="end-client.sh" type="bash">
<![CDATA[
export startdate=230801000000Z  # YYMMDDHHMMSSZ
export enddate=240731000000Z  # YYMMDDHHMMSSZ
openssl rand -hex $sn > $dir/serial # hex 8 is minimum, 20 is maximum
# Note 'openssl ca' does not support DER format
openssl ca -config $dir/openssl.cnf\
    -extensions usr_cert -notext \
    -in $dir/csr/$clientemail.csr.$format\
    -out $dir/certs/$clientemail.cert.$format
chmod 444 $dir/certs/$clientemail.cert.$format

openssl verify -CAfile $dir/certs/ca-chain.cert.$format\
     $dir/certs/$clientemail.cert.$format
openssl x509 -noout -text -in $dir/certs/$clientemail.cert.$format

openssl x509 -in $dir/certs/$clientemail.cert.$format\
      -out $dir/certs/$clientemail.cert.der -outform der
]]>
</sourcecode>
</section>
</section>
<section anchor="Intermediate8021ARLevel" title="The 802.1AR Intermediate level">
<section anchor="Step8021AR" title="Setting up the 802.1AR Intermediate Certificate Environment">
<t>
	There is no longer a need for a special 802.1AR Intermediate 
	Certificate CA.  The regular Intermediate Certificate CA may be 
	used for 802.1AR iDevID certificates.  A special CA may be set up 
	by following the steps outlined in <xref target="IntermediateLevel" 
	/>, but into a separate intermediate8021AR directory.
</t>
<t>
	The difference with 802.1AR device certificates may be in including 
	in the subject the device serial number.  802.1AR iDevID 
	certificates MUST have an afterDate of forever and a specific 
	subjectAltName with the hardwareModuleName OID <xref 
	target="RFC4108" format="default"/>. Details for these 
	follow.
</t>
</section>
<section anchor="Cert8021AR" title="Create an 802.1AR iDevID Certificate">
<t>
	Here are the openssl commands to create a 802.1AR iDevID
	certificate keypair, iDevID certificate signed request (CSR), and
	the iDevID certificate.  Included are commands to view the file
	contents.
</t>
<sourcecode anchor="Fig_9.1" name="idevid-csr-cert.sh" type="bash">
<![CDATA[
DevID=Wt1234
countryName=
stateOrProvinceName=
localityName=
organizationName="/O=HTT Consulting"
organizationalUnitName="/OU=Devices"
commonName=
serialNumber="/serialNumber=$DevID"
DN=$countryName$stateOrProvinceName$localityName
DN=$DN$organizationName$organizationalUnitName$commonName
DN=$DN$serialNumber
echo $DN

# hwType is OID for HTT Consulting, devices, sensor widgets
export hwType=1.3.6.1.4.1.6715.10.1
export hwSerialNum=01020304 # Some hex
export subjectAltName="otherName:1.3.6.1.5.5.7.8.4;SEQ:hmodname"
echo  $hwType - $hwSerialNum

openssl genpkey -algorithm $algorithm\
    -out $dir/private/$DevID.key.$format
# For ECDSA point-compression
#openssl ec -conv_form compressed \
#    -in $dir/private/$DevID.key.$format\
#    -out $dir/private/$DevID.key.$format
chmod 400 $dir/private/$DevID.key.$format
openssl pkey -in $dir/private/$DevID.key.$format -text -noout
openssl req -config $dir/openssl.cnf -reqexts req_ext_8021AR \
    -key $dir/private/$DevID.key.$format \
    -subj "$DN" -new -out $dir/csr/$DevID.csr.$format

openssl req -text -noout -verify\
    -in $dir/csr/$DevID.csr.$format
openssl asn1parse -i -in $dir/csr/$DevID.csr.pem
# offset of start of hardwareModuleName and use that in place of 169
openssl asn1parse -i -strparse 169 -in $dir/csr/$DevID.csr.pem
]]>
</sourcecode>
<sourcecode anchor="Fig_9.2" name="idevid-csr-cert.sh" type="bash">
<![CDATA[
export startdate=230801000000Z  # YYMMDDHHMMSSZ
export enddate=99991231235959Z # per IEEE 802.1AR
openssl rand -hex $sn > $dir/serial # hex 8 is minimum, 20 is maximum
# Note 'openssl ca' does not support DER format
openssl ca -config $dir/openssl.cnf\
    -extensions 8021ar_idevid -notext \
    -in $dir/csr/$DevID.csr.$format\
    -out $dir/certs/$DevID.cert.$format
chmod 444 $dir/certs/$DevID.cert.$format

openssl verify -CAfile $dir/certs/ca-chain.cert.$format\
     $dir/certs/$DevID.cert.$format
openssl x509 -noout -text -in $dir/certs/$DevID.cert.$format
openssl asn1parse -i -in $dir/certs/$DevID.cert.pem

# offset of start of hardwareModuleName and use that in place of 367
openssl asn1parse -i -strparse 367 -in $dir/certs/$DevID.cert.pem

openssl x509 -in $dir/certs/$DevID.cert.$format\
      -out $dir/certs/$DevID.cert.der -outform der
]]>
</sourcecode>
</section>
</section>
<section anchor="CRL" title="Setting up a CRL for an Intermediate CA">
<t>
	This part provides CRL support to an Intermediate CA.  In this memo
	it applies to both Intermediate CAs.  Set the crlDistributionPoints
	as provided via the environment variables.
</t>
<section anchor="createCRL" title="Create (or recreate) the CRL">
<t>
	It is simple to create the CRL.  The CRL consists of the
	certificates flagged with an R (Revoked) in index.txt:
</t>
<sourcecode anchor="Fig_10" name="crl-creation.sh" type="bash">
<![CDATA[
# Select which Intermediate level
intermediate=intermediate
#intermediate=8021ARintermediate
dir=$cadir/$intermediate
crl=$intermediate.crl.pem
cd $dir

# Create CRL file
openssl ca -config $dir/openssl.cnf \
      -gencrl -out $dir/crl/$crl
chmod 444 $dir/crl/$crl

openssl crl -in $dir/crl/$crl -noout -text
]]>
</sourcecode>
</section>
<section anchor="RevokeCert" title="Revoke a Certificate">
<t>
	Revoking a certificate is a two step process.  First identify the
	target certificate, examples are listed below.  Revoke it then
	publish a new CRL.
</t>
<sourcecode anchor="Fig_11" name="revoke-step1.sh" type="bash">
<![CDATA[
targetcert=$serverfqdn
#targetcert=$clientemail
#targetcert=$DevID

openssl ca -config $dir/openssl.cnf\
 -revoke $dir/certs/$targetcert.cert.$format
]]>
</sourcecode>
<t>
	Recreate the CRL using <xref target="createCRL" />.
</t>
</section>
</section>
<section anchor="OCSP" title="Setting up OCSP for an Intermediate CA">
<t>
	This part provides OCSP support to an Intermediate CA.  In this
	memo it applies to both Intermediate CAs.  Set the
	authorityInfoAccess as provided via the environment variables.
</t>
<section anchor="createOCSP" title="Create the OCSP Certificate">
<t>
	OCSP needs a signing certificate.  This certificate must be signed
	by the CA that signed the certificate being checked.  The steps to
	create this certificate is the similar to a Server certificate for
	the CA:
</t>
<sourcecode anchor="Fig_12.1" name="ocsp-setup.sh" type="bash">
<![CDATA[
# Select which Intermediate level
intermediate=intermediate
#intermediate=8021ARintermediate
# Optionally, password encrypt key pair
encryptkey=
#encryptkey=-aes256

# Create the key pair in Intermediate level $intermediate
cd $dir
openssl genpkey -algorithm $algorithm\
    $encryptkey -out $dir/private/$ocspurl.key.$format
# For ECDSA point-compression
#openssl ec -conv_form compressed \
#    -in $dir/private/$ocspurl.key.$format\
#    -out $dir/private/$ocspurl.key.$format
chmod 400 $dir/private/$ocspurl.key.$format
openssl pkey -in $dir/private/$ocspurl.key.$format -text -noout

# Create CSR
commonName="/CN=ocsp"
DN=$countryName$stateOrProvinceName$localityName
DN=$DN$organizationName$organizationalUnitName$commonName
echo $DN
emailaddr=postmaster@htt-consult.com
export subjectAltName="DNS:$ocspurl, email:$emailaddr"
echo $subjectAltName
openssl req -config $dir/openssl.cnf -reqexts req_ext_bks \
    -key $dir/private/$ocspurl.key.$format \
    -subj "$DN" -new -out $dir/csr/$ocspurl.csr.$format

openssl req -text -noout -verify -in $dir/csr/$ocspurl.csr.$format
]]>
</sourcecode>
<sourcecode anchor="Fig_12.2" name="ocsp-setup.sh" type="bash">
<![CDATA[
# Create Certificate

export startdate=230801000000Z  # YYMMDDHHMMSSZ
export enddate=99991231235959Z # per IEEE 802.1AR
openssl rand -hex $sn > $dir/serial # hex 8 is minimum, 20 is maximum
# Note 'openssl ca' does not support DER format
openssl ca -config $dir/openssl.cnf\
    -extensions ocsp -notext \
    -in $dir/csr/$ocspurl.csr.$format\
    -out $dir/certs/$ocspurl.cert.$format
chmod 444 $dir/certs/$ocspurl.cert.$format

openssl verify -CAfile $dir/certs/ca-chain.cert.$format\
     $dir/certs/$ocspurl.cert.$format
openssl x509 -noout -text -in $dir/certs/$ocspurl.cert.$format
]]>
</sourcecode>
</section>
<section anchor="RevokeCertOCSP" title="Revoke a Certificate">
<t>
	Revoke the certificate as in <xref target="RevokeCert" />.  The
	OCSP responder SHOULD detect the flag change in index.txt and, when
	queried respond appropriately.
</t>
</section>
<section anchor="TestingOCSP" title="Testing OCSP with Openssl">
<t>
	OpenSSL provides a simple OCSP service that can be used to test the
	OCSP certificate and revocation process (Note that this only reads
	the index.txt to get the certificate status at startup).
</t>
<t>
	In a terminal window, set variables dir and ocspurl (examples
	below), then run the simple OCSP service:
</t>
<sourcecode anchor="Fig_13" name="run-ocsp-server.sh" type="bash">
<![CDATA[
dir=/root/ca/intermediate
ocspurl=ocsp.htt-consult.com

openssl ocsp -port 2560 -text\
      -index $dir/index.txt \
      -CA $dir/certs/ca-chain.cert.pem \
      -rkey $dir/private/$ocspurl.key.pem \
      -rsigner $dir/certs/$ocspurl.cert.pem \
      -nrequest 1
]]>
</sourcecode>
<t>
	In another window, test out a certificate status with:
</t>
<sourcecode anchor="Fig_14" name="test-ocsp-server.sh" type="bash">
<![CDATA[
targetcert=$serverfqdn
#targetcert=$clientemail
#targetcert=$DevID

openssl ocsp -CAfile $dir/certs/ca-chain.cert.pem \
      -url http://127.0.0.1:2560 -resp_text\
      -issuer $dir/certs/intermediate.cert.pem \
      -cert $dir/certs/$targetcert.cert.pem
]]>
</sourcecode>
<t>
	Revoke the certificate, <xref target="RevokeCert" />, restart the
	test Responder again as above, then check the certificate status.
</t>
</section>
</section>
<section anchor="Footnotes" title="Footnotes">
<t>
	Creating this document was a real education in the state of
	openSSL, X.509 certificate guidance, and just general level of
	certificate awareness.  Here are a few short notes.
</t>
<section anchor="SerNum" title="Certificate Serial Number">
<t>
	The certificate serial number's role is to provide yet another way
	to maintain uniqueness of certificates within a PKI as well as a
	way to index them in a data store.  It has taken on other roles,
	most notably as a defense.
</t>
<t>
	The CABForum guideline for a public CA is for the serial number to 
	be a random number at least 8 octets long and no longer than 20 
	bytes.  <xref target="RFC5280" section="B" format="default"/> 
	states that "CAs MUST force the serialNumber to be a non-negative 
	integer, that is, the sign bit in the DER encoding of the INTEGER 
	value MUST be zero".
</t>
<t>
	By default, openssl makes self-signed certificates with 8 octet 
	serial numbers.  This guide uses openssl's RAND function to 
	generate a random value and pipe it into the serial file which is 
	used in by the config file.  This number MAY have the first bit as 
	a ONE; the DER encoding rules prepend such numbers with 0x00. Thus 
	increasing the actual certificate size by a byte.
</t>
<t>
	An 8-byte serial number with the first bit of zero can be generated 
	by limiting the random generation to less than 2^63:
</t>
<sourcecode anchor="Fig_15" name="sample-serial.sh" type="bash">
<![CDATA[
printf "%016X\n" $(shuf -rn 1 -i 1-9223372036854775807 \
--random-source=/dev/urandom) > $dir/serial

# or

printf "%016X\n" $((16#$(openssl rand -hex 8) & 0x7fffffffffffffff))\
 > $dir/serial
]]>
</sourcecode>
<t>
	A private CA need not follow the CABForum rules and can use
	anything number for the serial number.  For example, the root CA
	(which has no security risks mitigated by using a random value)
	could use '1' as its serial number.  Intermediate and End Entity
	certificate serial numbers can also be of any value if a strong
	hash, like SHA256 used here.  A value of 4 for ns would provide a
	sufficient population so that a CA of 10,000 EE certificates will
	have only a 1.2% probability of a collision.  For only 1,000
	certificates the probability drops to 0.012%.
</t>
<t>
	The following was proposed on the openssl-user list as an
	alternative to using the RAND function:
</t>
<t>
	Keep k bits (k/8 octets) long serial numbers for all your
	certificates, chose a block cipher operating on blocks of k bits,
	and operate this block cipher in CTR mode, with a proper secret key
	and secret starting counter. That way, no collision detection is
	necessary, you’ll be able to generate 2^(k/2) unique k bits longs
	serial numbers (in fact, you can generate 2^k unique serial
	numbers, but after 2^(k/2) you lose some security guarantees).
</t>
<t>
	With 3DES, k=64, and with AES, k=128.
</t>
</section>
<section anchor="Config" title="Some OpenSSL config file limitations">
<t>
	There is a bit of inconsistency in how different parts and fields
	in the config file are used.  Environment variables can only be
	used as values.  Some fields can have null values, others cannot.
	The lack of allowing null fields means a script cannot feed in an
	environment variable with value null.  In such a case, the field
	has to be removed from the config file.
</t>
<t>
	The expectation is each CA within a PKI has its own config file,
	customized to the certificates supported by that CA.
</t>
</section>
<section anchor="SAN" title="subjectAltName support now works">
<t>
	Older versions of openSSL had limitations in support for 
	subjectAltName (SAN).  This is no longer the case.  This document 
	sets up the SAN in the config file.  Alternatively, the "-addext" 
	option can be used directly in the command line.
</t>
</section>
<section anchor="CriticalSAN" title="Certificates with only subjectAltName">
<t>
	In <xref target="RFC5280" section="4.2.1.6" format="default"/>:  if
	the only subject identity in the certificate is in subjectAltName,
	then Subject MUST be empty and subjectAltName MUST be marked as
	critical.
</t>
<t>
	This can be achieved with the variable DN=/ and subjectAltName
	(example given):
</t>
<sourcecode anchor="Fig_16" name="sample-SAN.sh" type="bash">
<![CDATA[
DN=/
export subjectAltName=critical,email:postmaster@htt-consult.com
]]>
</sourcecode>
</section>
<section anchor="DER" title="DER support, or lack thereof">
<t>
	The long, hard-fought battle with openssl to create a full DER PKI 
	failed.  There is no facility to create a DER certificate from a 
	DER CSR.  It just is not there in the 'openssl ca' command.  Even 
	the 'openssl x509 -req' command cannot do this for a simple 
	certificate.
</t>
<t>
	Further, there is no 'hack' for making a certificate chain as there
	is with PEM.  With PEM a simple concatenation of the certificates
	create a usable certificate chain.  For DER, some recommend using
	<xref target="RFC2315">PKCS#7</xref>, where others point out that
	this format is poorly support 'in the field', whereas <xref
	target="RFC7292">PKCS#12</xref> works for them.
</t>
<t>
	Finally, openssl does support converting a PEM certificate to DER:
</t>
<sourcecode anchor="Fig_17" name="sample-pem-der.sh" type="bash">
<![CDATA[
openssl x509 -outform der -in certificate.pem -out certificate.der
]]>
</sourcecode>
<t>
	This should also work for the keypair.  However, in a highly
	constrained device it may make more sense to just store the raw
	keypair in the device's very limited secure storage.
</t>
</section>
</section>
<section anchor="IANA" title="IANA Considerations">
<t>
        TBD.  May be nothing for IANA.
</t>
</section>
<section title="Security Considerations">
<section anchor="Randomness" title="Adequate Randomness">
<t>
	Creating certificates takes a lot of random numbers.  A good source 
	of random numbers is critical.  <xref 
	target="WeakKeys">Studies</xref> have found excessive amount of 
	certificates, all with the same keys due to bad randomness on the 
	generating systems.  The amount of entropy available for these 
	random numbers can be tested.  On Fedora/Centos and most Linux 
	systems use:
</t>
<sourcecode anchor="Fig_18" name="chk-entropy.sh" type="bash">
<![CDATA[
cat /proc/sys/kernel/random/entropy_avail
]]>
</sourcecode>
<t>
	If the value is low (below 1000) check your system's randomness
	source.  Is rng-tools installed?  Consider adding an entropy
	collection service like haveged from issihosts.com/haveged.
</t>
</section>
<section anchor="Theft" title="Key pair Theft">
<t>
	During the certificate creation, particularly during keypair
	generation, the files are vulnerable to theft.  This can be
	mitigate using umask.  Before using openssl, set umask:
</t>
<sourcecode anchor="Fig_19" name="set-umask.sh" type="bash">
<![CDATA[
restore_mask=$(umask -p)
umask 077
]]>
</sourcecode>
<t>
	Afterwards, restore it with:
</t>
<sourcecode anchor="Fig_20" name="restore-umask.sh" type="bash">
<![CDATA[
$restore_mask
]]>
</sourcecode>
<t>
	or just close the shell that was used, and start a new one.  (The 
	-p option to umask is a bash-ism)
</t>
<t>
	There is nothing in these recipes that requires super-user on the 
	system creating the certificates.  Provided that adequate 
	randomness is available, a virtual machine or container is entirely 
	appropriate.  Containers tend to have better access to randomness 
	than virtual machines.
</t>
<t>
	The scripts and configuration files and in particular, private 
	keys, may be kept offline on a USB key for instance, and loaded 
	when needed.
</t>
<t>
	The OCSP server needs to be online and available to all clients 
	that will use the certificates. This may mean available on the 
	Internet.  A firewall can protect the OCSP server, and 
	port-forwards and/or ACL rules can restrict access to just the OCSP 
	port.  OCSP artifacts are signed by a key designed for that purpose 
	only so do not require that the associated CA key be available 
	online.
</t>
<t>
	Generating new CRLs, however, requires that the CA signing key be 
	online, which is one of the reasons for creating an intermediate 
	CA.
</t>
</section>
</section>
<section title="Acknowledgments">
<t>
	This work was jump started by the excellent RSA pki guide by Jamie
	Nguyen.  The openssl-user mailing list, with its many supportive
	experts; in particular:  Rich Salz, Jakob Bolm, Viktor Dukhovni,
	and Erwann Abalea, was of immense help as was the openssl man pages
	website.
</t>
<t>
	Finally, "Professor Google" was always ready to point to answers to
	questions like: "openssl subjectAltName on the command line".  And
	the Professor, it seems, never tires of answering even trivial
	questions.
</t>
<t>
	The openssl-user mailing list, with its many supportive experts, 
	was of immense help in the nuance differences between ECDSA and 
	EdDSA.
</t>
<t>
	The sourcecode blocks are structured to work with Carsten Bormann's 
	kramdown-rfc-extract-sourcecode script.  At the time of 
	publication, this script was part of the gem kramdown-rfc 
	collection.
</t>
</section>
</middle>
<back>
<displayreference target="I-D.moskowitz-ecdsa-pki" to="ecdsa-pki"/>
<displayreference target="I-D.moskowitz-drip-dki" to="drip-dki"/>
<displayreference target="DOI_10.6028_NIST.FIPS.186-5" to="NIST.FIPS.186-5"/>
<displayreference target="DOI_10.1109_IEEESTD.2018.8423794" to="IEEE 802.1AR"/>
<references> <name>References</name>
<references title="Normative References">
	<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
	<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
</references>
<references title="Informative References">
	<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2315.xml"/>
	<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4108.xml"/>
	<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5280.xml"/>
	<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7292.xml"/>
	<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8032.xml"/>
	<xi:include href="https://datatracker.ietf.org/doc/bibxml3/draft-moskowitz-ecdsa-pki.xml"/>
	<xi:include href="https://datatracker.ietf.org/doc/bibxml3/draft-moskowitz-drip-dki.xml"/>
	<xi:include href="https://bib.ietf.org/public/rfc/bibxml7/reference.DOI.10.6028/NIST.FIPS.186-5.xml"/>
	<xi:include href="https://bib.ietf.org/public/rfc/bibxml7/reference.DOI.10.1109/IEEESTD.2018.8423794.xml"/>
	<reference anchor="WeakKeys" target="https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final228.pdf">
  <front> <title>Detection of Widespread Weak Keys in Network Devices</title>
<author fullname="Nadia Heninger" initials="N.H." surname="Heninger">
	<organization>University of California, San Diego</organization>
	<address/>
</author>
<author fullname="Zakir Durumeric" initials="Z.D." surname="Durumeric">
	<organization>The University of Michigan</organization>
	<address/>
</author>
<author fullname="Eric Wustrow" initials="E.W." surname="Wustrow">
	<organization>The University of Michigan</organization>
	<address/>
</author>
<author fullname="J. Alex Halderman" initials="J.A.H." surname="Halderman">
	<organization>The University of Michigan</organization>
	<address/>
</author>
<date month="July" year="2011"/>
</front>
</reference>
</references>
</references>
<section anchor="configfile" title="OpenSSL config file">
<t>
	The following is the openssl.cnf file contents
</t>
<sourcecode anchor="Fig_21" name="openssl.cnf" type="conf">
<![CDATA[
# OpenSSL CA configuration file.
# Copy to `$dir/openssl.cnf`.

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = $ENV::dir
cadir             = $ENV::cadir
format            = $ENV::format
signprv           = $ENV::signprv
signcert          = $ENV::signcert
certkeyusage      = $ENV::certkeyusage
certextkeyusage   = $ENV::certextkeyusage
basicConstraints  = $ENV::basicConstraints

certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand

# The signing key and signing certificate.
private_key       = $cadir/private/$signprv.key.$format
certificate       = $cadir/certs/$signcert.cert.$format

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_startdate = $ENV::startdate
default_enddate   = $ENV::enddate
preserve          = no
policy            = policy_loose
copy_extensions   = copy

[ policy_loose ]
# Allow the intermediate CA to sign a more
#   diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = optional
UID                     = optional
serialNumber            = optional


[ req ]
# Options for the `req` tool (`man req`).
distinguished_name  = req_distinguished_name
string_mask         = utf8only
#req_extensions      = req_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
#countryName                     = Country Name (2 letter code)
#stateOrProvinceName             = State or Province Name
#localityName                    = Locality Name
#0.organizationName              = Organization Name
#organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name

[ req_ext ]

[ req_ext_bkes ]
basicConstraints = $ENV::basicConstraints
keyUsage = $ENV::certkeyusage
extendedKeyUsage = $ENV::certextkeyusage
subjectAltName = $ENV::subjectAltName

[ req_ext_bke ]
basicConstraints = $ENV::basicConstraints
keyUsage = $ENV::certkeyusage
extendedKeyUsage = $ENV::certextkeyusage

[ req_ext_bks ]
basicConstraints = $ENV::basicConstraints
keyUsage = $ENV::certkeyusage
subjectAltName = $ENV::subjectAltName

[ req_ext_bk ]
basicConstraints = $ENV::basicConstraints
keyUsage = $ENV::certkeyusage

[ req_ext_8021AR ]
basicConstraints = $ENV::basicConstraints
keyUsage = $ENV::certkeyusage
subjectAltName = $ENV::subjectAltName

[ hmodname ]
hwType = OID:$ENV::hwType
hwSerialNum = FORMAT:HEX,OCT:$ENV::hwSerialNum

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
basicConstraints = $ENV::basicConstraints
keyUsage = $ENV::certkeyusage

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
# basicConstraints = $ENV::basicConstraints
# keyUsage = $ENV::certkeyusage
# subjectAltName = $ENV::subjectAltName

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
# uncomment the following if the ENV variables set
# crlDistributionPoints = $ENV::crlDP
# authorityInfoAccess = $ENV::ocspIAI

[ usr_req ]
# Extensions for client certificates (`man x509v3_config`).
subjectAltName = critical, $ENV::subjectAltName


[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
# uncomment the following if the ENV variables set
# crlDistributionPoints = $ENV::crlDP
# authorityInfoAccess = $ENV::ocspIAI

[ 8021ar_idevid ]
# Extensions for IEEE 802.1AR iDevID
#   certificates (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
# uncomment the following if the ENV variables set
# crlDistributionPoints = $ENV::crlDP
# authorityInfoAccess = $ENV::ocspIAI

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
]]>
</sourcecode>
</section>
</back>
</rfc>
