<?xml version="1.0"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
There has to be one entity for each item to be referenced. 
An alternate method (rfc include) is described in the references.
-->
<!ENTITY TLS SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5246.xml">
<!ENTITY RFC1423 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.1423.xml">
<!ENTITY RFC2898 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2898.xml">
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2434 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2434.xml">
<!ENTITY RFC2437 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2437.xml">
<!ENTITY RFC5208 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5208.xml">
<!ENTITY RFC5958 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5958.xml">
<!ENTITY RFC5915 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5915.xml">
<!ENTITY RFC7292 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7292.xml">
<!ENTITY RFC7468 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7468.xml">
<!ENTITY RFC7512 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7512.xml">
<!ENTITY DTLS SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6347.xml">
<!ENTITY RFC8410 SYSTEM	"http://xml.resource.org/public/rfc/bibxml/reference.RFC.8410.xml">
<!ENTITY I-D.mavrogiannopoulos-tpmuri SYSTEM
	"http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-mavrogiannopoulos-tpmuri-01.xml">

]>
<?rfc toc="no"?>
<?rfc symrefs="yes"?>
<rfc ipr="trust200902" category="bcp" docName="draft-woodhouse-cert-best-practice-01">
  <front>
    <title abbrev="Certificate best practice">Recommendations for applications using X.509 client certificates</title>
    <author initials="D." surname="Woodhouse" fullname="David Woodhouse">
      <organization>Amazon Web Services</organization>
      <address>
        <postal>
          <street/>
          <city/>
          <region/>
          <country>UK</country>
        </postal>
        <email>dwmw2@infradead.org</email>
      </address>
    </author>
    <author initials="N." surname="Mavrogiannopoulos" fullname="Nikos Mavrogiannopoulos">
      <address>
        <postal>
          <street/>
          <city>Brno</city>
          <region/>
          <country>Czech Republic</country>
        </postal>
        <email>n.mavrogiannopoulos@gmail.com</email>
      </address>
    </author>
    <date month="July" year="2023"/>
    <area>Security</area>
    <!--      <workgroup>TLS Working Group</workgroup> -->
    <keyword>I-D</keyword>
    <keyword>Internet-Draft</keyword>
    <keyword>X.509</keyword>
    <keyword>TLS</keyword>
    <keyword>Transport Layer Security</keyword>
    <abstract>
      <t>
	X.509 certificates are widely used for client authentication
	in many protocols, especially in conjunction with Transport
	Layer Security (<xref target="RFC5246"/>) and Datagram Transport Layer Security
	(<xref target="RFC6347"/>. There exist a multitude of forms in which certificates
	and especially their corresponding private keys may be stored
	or referenced.
      </t>
      <t>
	Applications have historically been massively inconsistent in
	which subset of these forms have been supported, and what
	knowledge is demanded of the user. This memo sets out best
	practice for applications in the interest of usability and
	consistency.
      </t>
    </abstract>
  </front>
  <middle>
    <section anchor="intro" title="Introduction">
      <t>
	These recommendations are intended to provide consistency and
	simplicity to users. If a user has a client certificate in a
	file, or residing in a hardware or software token or a system
	certificate store, it should be possible to use that
	certificate from any application, using exactly the same
	identifier (e.g. its filename or PKCS#11 URI <xref
	target="RFC7512"/>) to reference it.
      </t>
      <t>
	No additional information should be required from the user
	other than perhaps a password; the user should certainly never
	be expected to know about which of the myriad possible formats
	the key or certificate are stored in.
      </t>
    </section>
    <section anchor="terms" title="Terminology">
      <t>
        The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
        NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
        "OPTIONAL" in this document are to be interpreted as described in
        <xref target="RFC2119"/>.
      </t>
      <t>
	Unless explicitly indicated otherwise, the terms "application"
	and "applications" in this document refer to client
	applications making use of X.509 certificates for
	authentication and signatures. Except where explicitly
	referenced in <xref target="writing"/>, tools which generate
	certificate and public key files are outside the scope of this
	document. As noted in <xref target="security"/>, the security
	considerations when generating or accepting a given certificate
	are markedly different to the considerations when presenting
	that same certificate as evidence of client identity.
      </t>
      <t>
	In particular, where this document requires that an
	application "support" a given type of key or storage format,
	that is limited strictly to reading and using the certificates
	and private keys. Support for creating and writing such
	objects is an orthogonal concern, and generally outside the
	scope of client applications.
      </t>
    </section>
    <section anchor="keytypes" title="Key types">
      <t>
	Applications MUST NOT be limited to using only RSA keys. An application:
      <list style="symbols">
	<t>MUST support RSA keys of 1024, 2048, 3072 and 4096 bits</t>
	<t>SHOULD support RSA keys of other arbitrary sizes, including non power-of-two sizes</t>
	<t>MAY support DSA keys of 1024 bits</t>
	<t>MUST support ECDSA keys based on SECP256R1, SECP384R1, SECP521R1 curves</t>
	<t>SHOULD support EdDSA keys based on Ed25519 curve</t>
	<t>SHOULD support ECDSA or EdDSA keys based on other well-known curves</t>
      </list>
      </t>
      <t>
	Where opaque keys such as in hardware tokens are used,
	applications MUST support the use of private keys where the
	corresponding public key is not made available to software.
	In particular, PKCS#11 tokens containing an EC private key and
	no corresponding public key object MUST be supported when
	PKCS#11 is supported.
      </t>
      <t>
	The use of DSA keys larger than 1024 bits is undefined in TLS
	and is thus not included in these recommendations, although
	applications MAY choose to support such keys. See also <xref
	target="security"/> regarding the use of key sizes and types
	regarded to be obsolescent.
      </t>
      <t>
        Note that in this text we explicitly mention ECDSA keys to distinguish
        them from static ECDH keys, which have no significant deployment nor
        use in Internet protocols. ECDSA keys are distinguished from static ECDH
        keys by having a certificate which allows signing (in contrast to keyAgreement
        for static ECDH keys).
      </t>
    </section>

    <section anchor="identifiers" title="Identifier types">
      <t>
	There are a number of forms which a certificate identifier
	might take. Applications MAY require that the user explicitly
	disambiguate between an inline data blob as discussed in <xref
	target="ident-blob"/>, and an identifier which is merely a
	reference to the location of the object, such as a filename or
	other identifier addressed in the other subsections below.
      </t>
      <t>
	Applications MUST NOT require that the user disambiguate
	between other types of identifiers. For example, where PKCS#11
	is supported an application MUST automatically infer that the
	reference it has been given is a PKCS#11 URI rather than a
	filename, without being explicitly directed to do so by a
	separate configuration directive. In the
	extremely unlikely case that ambiguity genuinely exists
	because a file has a name which starts with "pkcs11:" and is
	otherwise valid according to <xref target="RFC7512"/>, the
	user can resolve the ambiguity by specifying an absolute path
	to the file in question, or even a relative path prefixed with
	"./" or the appropriate equivalent for the platform in
	question.
      </t>
      <section anchor="ident-file" title="File name">
	<t>
	  Many applications support the use of certificates and
	  private keys stored in files on the file system. Such
	  applications MUST support the use of files in any of the
	  formats mandated in <xref target="formats"/>, in both PEM
	  and DER containers.
	</t>
	<t>
	  Applications MUST NOT require the user to provide any
	  additional hints regarding the contents of the file, such as
	  whether the contents are in PEM or DER format. This MUST be
	  determined by the application itself, automatically.
	</t>
	<t>
	  Applications MAY accept absolute or relative filenames,
	  and MAY also accept filenames in the form of a file:// URI.
	</t>
	<t>
	  On a platform where the use of certificates and keys from
	  files is commonplace, applications MUST support
	  such. Applications which do not support a system-wide
	  certificate store as discussed in <xref
	  target="ident-pkcs11"/> and/or <xref target="ident-system"/>
	  MUST support the use of certificates and keys from files.
	</t>
      </section>
      <section anchor="ident-blob" title="Inline data blob">
        <t>
	  In some cases, an application may accept certificate and
	  private key data in the form of inline data embedded
	  directly within its configuration. In this case,
	  applications MUST accept such data in any of the formats
	  mandated in <xref target="formats"/>.
	</t>
	<t>
	  As with files, applications MUST NOT require any additional
	  hint to be provided regarding the format of the provided blob.
	</t>
      </section>
      <section anchor="ident-pkcs11" title="PKCS#11 objects">
	<t>
	  On a platform which supports PKCS#11 <xref target="PKCS11"/>
	  and has a system-wide configuration indicating which which
	  PKCS#11 provider modules should be loaded, applications
	  SHOULD load the PKCS#11 providers indicated by the system
	  configuration. Applications MAY also load additional providers
	  according to their own configuration.
	</t>
	<t>
	  Applications which support PKCS#11 MUST accept certificate
	  and key identifiers in the form of a PKCS#11 URI <xref
	  target="RFC7512"/>. Objects SHOULD then be located by an
	  algorithm at least as capable as the one described in <xref
	  target="pkcs11search"/>.
	</t>
	<t>
	  Applications MUST allow a PIN to be provided in a
	  "pin-value" attribute in such a URI, and SHOULD also
	  allow a PIN to be provided via their normal mechanism for
	  obtaining passwords for private keys when stored in files.
	</t>
	<t>
	  Applications MAY accept legacy forms of identifier for
	  PKCS#11 objects, for backward compatibility if they did so
	  before the existence of RFC7512. They SHOULD NOT document
	  these legacy identifiers as current practice, and SHOULD
	  document the use of RFC7512 standard identifiers instead.
	</t>
      </section>
      <section anchor="ident-tpm" title="Trusted Platform Module (TPM) stored keys">
	<t>
	  Applications which run on a platform which contains a
	  Trusted Platform Module (TPM) conforming to the v2.0
	  specification (<xref target="TPMv2"/>) or newer SHOULD
	  support using it for key operations. Applications MAY
	  support the older TPM v1.2 stack.
	</t>
	<t>
	  Both versions of the TPM stack have support for non-volatile
	  storage and "wrapping" of keys. The latter requires storage
	  outside the TPM and is discussed alongside other file
	  formats in <xref target="format-tpm"/>.
	</t>
	<t>
	  If the older TPM v1.2 specification is supported,
	  applications SHOULD support referencing a key in its
	  non-volatile memory by use of a TPMKEY URI as defined in
	  <xref target="I-D.mavrogiannopoulos-tpmuri"/>. Applications
	  MAY support the tpmkey-file option defined therein but it
	  should be noted that the common tools do not create files in
	  the ASN.1 format required therein so this support is of
	  limited utility to the user. A better file format for TPM v1.2
	  support is described in <xref target="format-tpm"/>.
	</t>
	<t>
	  For keys stored in the TPM v2.0 non-volatile memory, no URI
	  form exists at the time of writing. If such a standard or
	  convention comes into existence, applications SHOULD support
	  it.
	</t>
      </section>
      <section anchor="ident-system" title="System store">
	<t>
	  Some operating systems have their own system store for
	  certificates and keys which is not based on
	  PKCS#11. Applications SHOULD support the use of objects from
	  such a system store, if it exists. If a convention or
	  standard exists for referencing objects therein, analogous
	  to the one defined for PKCS#11 by <xref target="RFC7512"/>,
	  then applications SHOULD accept such identifier strings.
	</t>
      </section>
    </section>

    <section anchor="formats" title="File formats">
      <t>
	There exist a multitude of formats in which certificates and
	their corresponding private keys can be stored, and new
	formats come into existence with distressing regularity.
      </t>
      <t>
	Users have little control over the form in which certificates
	are provisioned to them by their organisation's
	infrastructure. As a result, applications should be expected
	to deal with any of the formats listed below, as well as any
	newer forms which become common.
      </t>
      <t>
	The first difference that a user will typically encounter is
	that some objects are stored in base64 in text files (PEM)
	<xref target="RFC7468"/>, while others are binary (DER).
	Applications MUST NOT require that the user or the
	configuration specify which of these forms is used, and MUST
	infer it internally.
      </t>
      <t>
	Where an object is encoded directly in the configuration of an
	application and the contents of that configuration are limited
	to textual content, the application MAY support only objects
	in PEM form, and not binary DER. Such applications MUST still
	support the PEM representation of all formats listed below.
      </t>
      <t>
	Applications MUST accept all of the formats below without
	requiring any additional information from the user or the
	configuration. Where an application has an existing "key
	format" or similar option which has historically been required
	to disambiguate between formats (either the formats below or
	between PEM and DER), application SHOULD NOT document this use
	of that legacy option as current practice, and SHOULD default
	to working it out automatically. Application authors who
	cannot achieve this SHOULD consider taking up goat farming,
	and never touching a cryptographic application again in their
	life.
      </t>
      <section anchor="format-pkcs1" title="PKCS#1 and other native ASN.1 encodings">
	<t>
	  Applications MUST support unencrypted private keys:
	  <list style="symbols">
	    <t>RSA keys in PKCS#1 form as defined by <xref target="RFC2437"/></t>
	    <t>DSA keys in the ASN.1 form defined by OpenSSL and
	    documented in <xref target="openssl-dsa"/> (if DSA keys
	    are supported at all)</t>
	    <t>ECDSA keys in the form defined by <xref target="RFC5915"/></t>
	    <t>EdDSA keys in the form defined by <xref target="RFC8410"/></t>
	  </list>
	</t>
      </section>
      <section anchor="format-pkcs8" title="PKCS#8">
	<t>
	  Applications MUST support keys stored in PKCS#8 form as
	  defined in <xref target="RFC5208"/> for all key types. Applications MUST
	  support unencypted PKCS#8 objects, as well as those which
	  are encrypted in various forms as discussed in <xref
	  target="encryption"/>.
	</t>
	<t>
	  Applications MAY support the updated version of PKCS#8 is
	  defined in <xref target="RFC5958"/>. At the time of writing,
	  there does not seem to be widespread use of keys in the
	  new form, so such support is not mandatory.
	</t>
      </section>
      <section anchor="format-pkcs12" title="PKCS#12">
	<t>Applications MUST support the use of certificates and keys
	from PKCS#12 objects (<xref target="RFC7292"/>), encrypted
	with any of the the methods mandated in <xref
	target="encryption"/>. Applications MUST support the use of at
	least SHA1 and SHA256 HMAC, and SHOULD support other HMAC
	algorithms which become common.
      </t>
      </section>
      <section anchor="format-tpm" title="Trusted Platform Module (TPM) wrapped keys">
	<t>
	  As noted in <xref target="ident-tpm"/>, applications which run
	  on a system with a v2.0 or newer TPM SHOULD support using it
	  for key operations.
	</t>
	<t>
	  Applications supporting TPM v2.0 MUST automatically detect
	  files in the ASN.1 form defined in <xref
	  target="I-D.Bottomley-tpm2-asn1"/>, in DER form as well as
	  the PEM format with the tag "-----BEGIN TSS2 PRIVATE
	  KEY-----".
	</t>
	<t>
	  Since the native form of the TPM v1.2 key blob is not simple
	  to detect, applications MAY lack support for detecting the
	  binary form. This is an exception to the general rule that all
	  file types must be automatically detected without additional
	  user input.
	</t>
	<t>
	  The tpmkey-file option defined in
	  <xref target="I-D.mavrogiannopoulos-tpmuri"/> is also of limited
	  utility and need not be supported.
	</t>
	<t>
	  Rather, a common form of storage for "wrapped" keys with
	  TPM v1.2 is to encode the binary TCPA_KEY structure in a
	  single ASN.1 OCTET-STRING, and store the result in PEM
	  format with the tag "-----BEGIN TSS KEY
	  BLOB-----". Applications supporting TPM v1.2 MUST automatically
	  detect and support this format.
	</t>
      </section>
    </section>
    <section anchor="privkeys" title="Private keys">
    <section anchor="encryption" title="Encryption">
      <t>
	Applications MUST support the encrypted PEM files in the form
	based on <xref target="RFC1423"/> which is commonly used by
	historical versions of OpenSSL, with at least the DES-EDE3-CBC,
	AES-128-CBC and AES-256-CBC modes.
      </t>
      <t>
	For PKCS#12 <xref target="RFC7292"/> and PKCS#8 <xref
	target="RFC5208"/> formats, applications MUST support reading
	objects stored with the following encryption methods:
	<list style="symbols">
	  <t>PBES1 pbeWithMD5AndDES-CBC <xref target="RFC2898"/></t>
	  <t>PBES1 pbeWithSHA1And3-KeyTripleDES-CBC <xref target="RFC7292"/></t>
	  <t>PBES2 AES-128-CBC (OID: 2.16.840.1.101.3.4.1.2) <xref target="RFC2898"/></t>
	  <t>PBES2 AES-256-CBC (OID: 2.16.840.1.101.3.4.1.42) <xref target="RFC2898"/></t>
	</list>
      </t>
      <t>
	The weak methods included in the above list are unfortunately
	still commonplace, and thus clients need to keep supporting
	them as noted in <xref target="security"/>. However, applications
	MAY emit a warning to the user when weak (or no) encryption is
	used, and MAY require an additional configuration directive to
	enable the use of weakly-encrypted and unencrypted keys.
      </t>
      <t>
	The presence of these algorithms in the list is not in any way
	to be taken as approval for tools to continue creating objects
	in such forms. Except for a brief discussion in <xref
	target="writing"/>. the creation of private keys is outside
	the scope of this document.
      </t>
      <t>
	It should also be noted that this list is very much of its
	time. It reflects current common practice, but the latest
	methods on the list may also one day seem as outdated as
	the first. Applications SHOULD add support for newer
	methods as and when they become common.
      </t>
    </section>
    <section anchor="separatekey" title="Separation of certificate and private key">
      <t>
	It is not uncommon for a certificate and its corresponding
	private key to be stored in separate files. When loading certificates
	and keys, applications MUST support this by allowing the certificate
	and the private key to be specified separately.
      </t>
      <t>
	Applications MUST NOT require that the certificate and private
	key be in the same type of location — for example, both in
	files, or both in PKCS#11 objects. In particular, it is often
	the case that cryptographic hardware tokens only support
	private keys and do not provide any certificate storage. In
	that case, it is entirely normal for the certificate to be
	stored in a file while the key is accessed via PKCS#11.
      </t>
      <t>
	If the private key is not explicitly specified, then the
	application MUST attempt to find it based on the location of
	the certificate. For files, this would naturally mean looking
	in the same file. Applications MAY also make reasonable inferences,
	such as looking for a file with the extension ".key" if the certificate
	was in a file with the extension ".crt" and the key wasn't found therein.
      </t>
      <t>
	For PKCS#11, applications SHOULD search for a key using an algorithm
	at least as capable as the one described in <xref
	target="pkcs11search"/>.
      </t>
    </section>
    <section anchor="writing" title="Writing private key files">
      <t>
	In the general case, writing private key files is outside the
	scope of this document. These recommendations cover only the
	usage of certificate and private keys by client applications.
	An exception to this general case occurs when a client application
	supports exporting a certificate and private key from a certificate
	store to a file.
      </t>
      <t>
	When doing so, applications MUST allow exporting in at least
	the PKCS#12 <xref target="RFC7292"/> format under the
	following encryption methods:
	<list style="symbols">
	  <t>PBES2 AES-128-CBC (OID: 2.16.840.1.101.3.4.1.2) <xref target="RFC2898"/></t>
	  <t>PBES2 AES-256-CBC (OID: 2.16.840.1.101.3.4.1.42) <xref target="RFC2898"/></t>
	</list>
      </t>
      <t>
	Applications which export private keys in encrypted form MUST
	ensure that the password provided by the user is correctly
	converted to the required character set for the encryption.
	See notes in <xref target="passwords"/> regarding the ways in
	which this has historically been broken in some cases. For this
	reason, applications SHOULD export to PKCS#12 in preference to
	any other formats. If insufficiently-specified formats such as
	PKCS#8 are used for export, applications SHOULD convert the
	password to UTF-8 for the purpose of key derivation.
      </t>
      <t>
	Applications which export private keys to PKCS#12 SHOULD use a
	single passphrase for every encrypted bag therein.
      </t>
      <t>
	Applications which support a v2.0 TPM and are able to export
	the key information MUST do so in the PEM format described in
	<xref target="I-D.Bottomley-tpm2-asn1"/>.
      </t>
    </section>

    </section>
    <section anchor="passwords" title="Passwords and character sets">
      <t>
	Applications MUST allow at least one passphrase or PIN to be
	provided for private keys, either in advance through a
	separate configuration item or by means of a callback at
	runtime which can display a prompt to the user.
      </t>
      <t>
	Applications SHOULD, where possible, allow for the possibility
	that a single object may require more than one passphrase, as
	is the case of PKCS#12 objects.
      </t>
      <t>
	Applications which support PKCS#11 SHOULD support the use of
	keys with the CKA_ALWAYS_AUTHENTICATE attribute set to
	CK_TRUE. In this case the PIN will need to be provided to the
	PKCS#11 provider again for each cryptographic operation using
	the key.
      </t>
      <t>
	Applications SHOULD also allow for the possibility that a
	passphrase or PIN is required to access a certificate,
	separately from the passphrase or PIN required for the private
	key.
      </t>
      <t>
	Applications MUST be aware of the local character set in which
	the user provides the passphrase, and convert it as necessary.
      </t>
      <t>
	Password representations based on Unicode (BMPString for
	PKCS#12, UTF-8 for PKCS#5) SHOULD be normalized according to
	Unicode normalization form "NFC" <xref target="NFC"/>.
      </t>
      <section anchor="password-pkcs12" title="Passwords in PKCS#12">
	<t>
	  PKCS#12 <xref target="RFC7292"/> explicitly specifies the
	  character set to be used for the password in the key
	  derivation, as a BMPString.  When decrypting PKCS#12 objects
	  applications MUST correctly support conversion of passwords
	  to BMPString for the purpose of key derivation.
	</t>
	<t>
	  Applications SHOULD also attempt to work around the historical
	  PKCS#12 bug in OpenSSL, which always assumed the input
	  password was in the ISO8859-1 character set regardless of the
	  actual character set used on the system. This occurred because
	  it attempted to convert to UTF-16 for the BMPString merely by
	  alternating each byte from the input string with a zero byte
	  to expand to 16 bits.
	</t>
	<t>
	  As an example, consider a PKCS#12 file for which the password
	  is intended to be the following two characters:
	  <list>
	    <t>U+0102 LATIN CAPITAL LETTER A WITH BREVE</t>
	    <t>U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE</t>
	  </list>
	  For the purpose of this example, the user is operating in a
	  legacy 8-bit locale using the ISO8859-2 character set. The
	  above two characters are thus provided to the application as
	  the bytes 0xC3 0xAF.
	</t>
	<t>
	  The correct form of that password for PKCS#12 key derivation
	  includes precisely those characters in UTF-16 big-endian
	  form as required for a BMPString: the bytes 0x01 0x02 0x01
	  0x7B. This is the correct version which any application
	  supporting the use of files for certificates and keys MUST
	  support.
	</t>
	<t>
	  Historical versions of OpenSSL, as noted, would assume that
	  the input bytes were in the ISO8859-1 character set. So the
	  input bytes 0xC3 0xAF would therefore be interpreted as the
	  two characters:
	  <list>
	    <t>U+00C3 LATIN CAPITAL LETTER A WITH TILDE</t>
	    <t>U+00AF MACRON</t>
	  </list>
	  The BMPString used for key derivation in this case would
	  include the bytes 0x00 0xC3 0x00 0xAF.
	</t>
	<t>
	  An application in a non-ISO8859-1 locale can therefore attempt
	  to decrypt such wrongly-created files by treating the input
	  password as if it is a sequence of bytes in ISO8859-1 rather
	  than the locale character set in which it really was
	  provided. The application can generate the BMPString by
	  converting from ISO8859-1 to big-endian UTF-16, and attempt to
	  decrypt the file by deriving the key using that rendition of
	  the password.
	</t>
	<t>
	  From OpenSSL 1.1, the bug has been updated to the 21st century
	  without actually fixing it; OpenSSL merely assumes UTF-8
	  instead of ISO8859-1. So using the above example, OpenSSL
	  would interpret the (ISO8859-2) input bytes 0xC3 0xAF, by
	  wilfully ignoring their character set, wrongly assuming that
	  they are UTF-8 (in this case representing the single character
	  U+00EF LATIN SMALL LETTER I WITH DIAERESIS"), and converting
	  them to a BMPString containing the bytes 0x00 0xEF.
	</t>
	<t>
	  Applications MAY work around this new bug in OpenSSL, by
	  treating the input password as a UTF-8 byte stream. Note that
	  if the byte sequence of the input password doesn't happen to
	  be valid UTF-8, as it was in the carefully-contrived example
	  above, then OpenSSL 1.1 will revert to its old behaviour of
	  assuming ISO8859-1. In no circumstances does OpenSSL convert a
	  non-ASCII password correctly, in a locale which uses neither
	  UTF-8 nor ISO8859-1.
	</t>
      </section>
      <section anchor="password-pkcs5" title="PKCS#5 password derivation">
	<t>
	  Some storage formats such as PKCS#8 <xref target="RFC5208"/>
	  make use of key derivation functions defined in PKCS#5
	  <xref target="RFC2898"/> for encryption. Lamentably, PKCS#5
	  does not mandate the use of a specific character set for
	  interoperability. It does, however, recommend "that
	  applications follow some common text encoding rules.  ASCII
	  and UTF-8 are two possibilities."
	</t>
	<t>
	  Strictly speaking, that's only one possibility, since (as it
	  says) ASCII is a subset of UTF-8. In these recommendations,
	  therefore, client applications MUST render a non-ASCII
	  password into UTF-8 for the purpose of key derivation to
	  attempt to decrypt objects.
	</t>
	<t>
	  Applications operating in non-UTF-8 locales SHOULD also
	  attempt to decrypt such objects using a key derived from
	  the password in the local character set.
	</t>
      </section>
      <section anchor="password-pkcs11" title="PKCS#11 PIN">
	<t>
	  The PKCS#11 specification <xref target="PKCS11"/> specifies
	  that the CK_UTF8CHAR type used for the PIN "holds UTF-8
	  encoded Unicode charaacters as specified in RFC2279". Older
	  versions of the PKCS#11 specification limited the PIN still
	  further, to a subset of ASCII printable characters.
	</t>
	<t>
	  Thus, applications supplying a PIN to a PKCS#11 module MUST
	  convert from the character set in which the PIN was provided,
	  to UTF-8.
	</t>
	<t>
	  When a login with the PIN encoded in UTF-8 fails,
	  applications MUST NOT fall back to trying again with the
	  local character set. That behaviour is permitted for file
	  formats, where an additional failed decryption attempt would
	  be harmless. In PKCS#11, this would be likely to result in
	  tokens becoming locked due to excessive PIN failures.
	  It would be especially unwise given that using the PIN in
	  the local character set is known to be in violation of
	  the PKCS#11 specification and should always fail.
	</t>
      </section>
    </section>
    <section anchor="pkcs11search" title="Locating objects in PKCS#11">
      <t>
	The "PKCS#11 URI" defined by <xref target="RFC7512"/> is
	slightly misnamed because it does not define a unique
	identifier for a object; rather the attributes in the
	identifier string are a set of search criteria used to filter
	a set of objects.
      </t>
      <t>
	A recommended method of locating objects in PKCS#11 is
	presented here. It is not mandatory to follow precisely this
	algorithm, but applications SHOULD use a method which will
	result in them finding any object which would have been found
	by this method.
      </t>
      <section anchor="pkcs11-cert" title="Locating PKCS#11 certificates">
	<t>
	  For locating certificates, applications first iterate over the
	  available tokens without logging in to them. In each token
	  which matches the provided PKCS#11 URI, a search is performed
	  for matching certificate objects. The first matching object is
	  used as the certificate.
	</t>
	<t>
	  If no match is found, and precisely one token was matched by
	  the specified URI, then the application attempts to log in to
	  that token using a PIN which is provided in a "pin-value"
	  attribute of the URI, in a separate configuration option, or
	  via a run-time callback if appropriate. Another search is
	  performed for matching objects, which this time will return
	  even any certificate objects with the CKA_PRIVATE
	  attribute. Is it important to note that the login should only
	  be attempted if there is precisely one token which matches the
	  URI, and not if there are multiple possible tokens in which
	  the object could reside.
	</t>
      </section>
      <section anchor="pkcs11-key" title="Locating PKCS#11 keys">
	<t>
	  If a private key location in PKCS#11 is explicitly specified
	  as separate from the certificate, as discussed in <xref
	  target="separatekey"/>, then no inferences can be made about
	  its location based on the location of the
	  certificate. Applications should follow the same procedure
	  as in <xref target="pkcs11-cert"/> to locate the key.
	</t>
	<t>
	  If the key is not explicitly specified, however, and the
	  certificate was located in PKCS#11, then some assumptions
	  can be made to help find the key if it is not found by the
	  above method. In this case, the application should log
	  in to the token in which the certificate was found, and
	  perform a search using the original criteria specified in
	  the provided PKCS#11 URI. If the key is not found and the
	  original search was by CKA_LABEL of the certificate, then
	  repeat the search using the CKA_ID of the certificate that
	  was actually found, but not requiring a CKA_LABEL match.
	</t>
      </section>
    </section>
    <section anchor="validation" title="Validation and error handling">
      <t>
	Applications SHOULD validate that the certificate and private
	key they are requested to use are actually a matching pair,
	and report an error coherently to the user if not.
      </t>
      <t>
	Where the key is entirely visible to software, this can be a
	simple matter of comparing the public key parameters and many
	cryptographic libraries will do that automatically. Where an
	opaque key from hardware or a software API such as PKCS#11 is
	used, libraries often bypass this check and an application
	SHOULD explicitly ensure that it is performed, perhaps by
	performing a signature operation using the private key and
	then validating it against the certificate if necessary.
      </t>
      <t>
	Where appropriate, applications SHOULD check whether a
	certificate has expired or will imminently expire, and provide
	a suitable warning or error to the user.
      </t>
      <t>
	If an application is unable to use the designated certificate
	and private key for any reason, a coherent error report SHOULD
	be presented to the user explaining the reason for the failure.
      </t>
    </section>
    <section anchor="libraries" title="Library support">
      <t>
	The blame for the appalling historical state of applications
	with regard to these recommendations can be laid firmly at the
	door of the common cryptographic libraries. At the time of
	writing, most of them make it extremely hard for an
	application to follow these recommendations — when they should
	be making it hard for an application NOT to do so.
      </t>
      <t>
	It is hoped that cryptographic libraries will update their
	APIs to support the recommendations herein.
      </t>
    </section>
    <section anchor="security" title="Security Considerations">
      <t>
	Some might argue that these recommendations encourage the use
	of obsolescent algorithms and formats which do not conform to
	current cryptographic best practice. This may be true; however
	it is not the responsibility of the client application to
	enforce common sense in this respect.
      </t>
      <t>
	If a user is in possession of a certificate for a 1024-bit DSA
	key, for example, then we should focus on the server which is
	accepting those certificates or the PKI infrastructure which
	is issuing them — not the client which is attempting to use
	them.  Client software tends to move more quickly and be
	updated more frequently than servers, so algorithms may be
	considered deprecated by a client, while the server is still
	accepting them and an organisation's infrastruture is even
	still issuing certificates in that form.
      </t>
      <t>
	Likewise, it is common for private keys to be stored with weak
	encryption. Even in OpenSSL 1.0.2, the default for PKCS#8
	files is PBES1 and pbeWithMD5AndDES-CBC. Again, it is not the
	place of the client application to enforce sanity. Especially
	as there are valid reasons for accepting even unencrypted
	forms of private keys, so it makes little sense to then refuse
	to tolerate weakly-encrypted keys.
      </t>
    </section>
    <section anchor="IANA" title="IANA Considerations">
      <t>
	None.
      </t>
    </section>
  </middle>
  <back>
    <references title="Normative References">

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml"?-->
      &RFC2119;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2898.xml"?-->
      &RFC2898;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2437.xml"?-->
      &RFC2437;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.5208.xml"?-->
      &RFC5208;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.5958.xml"?-->
      &RFC5958;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.5915.xml"?-->
      &RFC5915;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.7292.xml"?-->
      &RFC7292;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.7468.xml"?-->
      &RFC7468;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.7512.xml"?-->
      &RFC7512;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.8410.xml"?-->
      &RFC8410;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-mavrogiannopoulos-tpmuri-01.xml"?-->
      &I-D.mavrogiannopoulos-tpmuri;

      <reference anchor="I-D.Bottomley-tpm2-asn1" target="https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html">
	<front>
	  <title>ASN.1 Specification for TPM 2.0 Key Files</title>
	  <author initials="J." surname="Bottomley" fullname="James Bottomley">
	    <organization>Linux Kernel</organization>
	  </author>
	  <date year="2023" month="April"/>
	</front>
      </reference>

      <reference anchor="TPMv2" target="https://trustedcomputinggroup.org/resource/tpm-library-specification/">
	<front>
	  <title>TPM 2.0 Library Specification</title>
	  <author><organization>Trusted Computing Group</organization></author>
	  <date year="2013" month="March"/>
	</front>
      </reference>

      <reference anchor="NFC" target="http://www.unicode.org/reports/tr15/">
	<front>
	  <title>Unicode Standard Annex #15: Unicode Normalization Forms</title>
	  <author initials="M." surname="Davis" fullname="Mark Davis">
	    <organization>Google</organization>
	  </author>
	  <author initials="K." surname="Whistler" fullname="Ken Whistler"/>
	  <date year="2016" month="February"/>
	</front>
      </reference>

    </references>
    <references title="Informative References">

      <reference anchor="PKCS11" target="http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html">
	<front>
	  <title>PKCS #11 Cryptographic Token Interface Base Specification Version 2.40</title>
	  <author><organization>OASIS PKCS#11 Technical Committee</organization></author>
	  <date year="2016" month="May"/>
	</front>
      </reference>

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.1423.xml"?-->
      &RFC1423;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.5246.xml"?-->
      &TLS;

      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.6347.xml"?-->
      &DTLS;

    </references>
    <section title="Acknowledgements">
      <t>
      </t>
    </section>
    <section anchor="openssl-dsa" title="DSA Private key description">
      <t>
The following figure describes the ASN.1 description of DSA private keys
generated by the openssl application. Today the DER encoding of this format
is a widely accepted standard format for storing DSA private keys. The stored
format may be either a raw DER encoding, or a PEM encoding with the header
"BEGIN DSA PRIVATE KEY".
      </t>
      <sourcecode type="asn.1" markers="false"><![CDATA[
DSA-Private-Key-Module
DEFINITIONS IMPLICIT TAGS ::=
BEGIN

DSAPrivateKey ::= SEQUENCE {
    version  INTEGER, -- should be zero
    p        INTEGER,
    q        INTEGER,
    g        INTEGER,
    pub      INTEGER, -- public
    priv     INTEGER, -- private
}
END
        ]]></sourcecode>
   </section>

  </back>
</rfc>
