-
Notifications
You must be signed in to change notification settings - Fork 1
/
draft-woodhouse-cert-best-practice.xml
941 lines (915 loc) · 39 KB
/
draft-woodhouse-cert-best-practice.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
<?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>