RFC 7512
The PKCS #11 URI Scheme
The PKCS #11 URI Scheme π
okay bestie, this is RFC 7512 π. It's a Standards Track document, so it's the serious, implementers-must-follow kind π₯. It was written by J. Pechanec and D. Moffat from Oracle Corporation, it's dated April 2015, and it's ISSN 2070-1721 β¨. The title block doesn't list any RFCs it obsoletes or updates, so it's not replacing or patching anything π§.
Abstract πΈ
so this memo defines a PKCS #11 Uniform Resource Identifier (URI) Scheme π¦. You use it to identify PKCS #11 objects that live inside PKCS #11 tokens, and also to identify PKCS #11 tokens, slots, or libraries π. The whole scheme is built on how PKCS #11 objects, tokens, slots, and libraries already get identified in "PKCS #11 v2.20: Cryptographic Token Interface Standard" π.
Status of This Memo π
this is an Internet Standards Track document π .
it's a product of the Internet Engineering Task Force (IETF) and it represents the consensus of the IETF community π«Ά. it got public review and was approved for publication by the Internet Engineering Steering Group (IESG) π. for more on Internet Standards, check Section 2 of RFC 5741 β¨.
if you want the current status, any errata, or a way to send feedback, go to http://www.rfc-editor.org/info/rfc7512 π.
Copyright Notice π
Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved. π
this document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stood on the publication date. please actually read those, they spell out your rights and restrictions π. and if you pull Code Components out of this document, they have to include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as described in the Simplified BSD License π.
Table of Contents π§
1. Introduction ....................................................2
2. PKCS #11 URI Scheme Definition ..................................4
2.1. PKCS #11 URI Scheme Name ...................................4
2.2. PKCS #11 URI Scheme Status .................................4
2.3. PKCS #11 URI Scheme Syntax .................................4
2.4. PKCS #11 URI Scheme Query Attribute Semantics ..............9
2.5. PKCS #11 URI Matching Guidelines ..........................11
2.6. PKCS #11 URI Comparison ...................................12
2.7. Generating PKCS #11 URIs ..................................14
3. Examples of PKCS #11 URIs ......................................14
4. IANA Considerations ............................................17
4.1. URI Scheme Registration ...................................17
5. Internationalization Considerations ............................18
6. Security Considerations ........................................18
7. References .....................................................19
7.1. Normative References ......................................19
7.2. Informative References ....................................19
Contributors ......................................................20
Authors' Addresses ................................................20
1. Introduction β¨
okay so "PKCS #11 v2.20: Cryptographic Token Interface Standard" [PKCS11] describes an API called Cryptoki, for devices that hold cryptographic information and do cryptographic functions π. Cryptoki (pronounced "crypto-key" and short for "cryptographic token interface") is object-based and simple π. it's all about technology independence (any kind of device can be used) and resource sharing (multiple applications can access multiple devices), and it gives apps one common, logical view of the device: a cryptographic token β¨.
it's really useful when apps or libraries that work with PKCS #11 tokens can accept one common identifier π«Ά. with it, consumers can point at an existing PKCS #11 storage object in a token, an existing token itself, a slot, or an existing Cryptoki library (also called a producer, module, or provider) π§. storage objects can be a certificate, a data object, or a public, private, or secret key π. this document's URI scheme is how you uniquely identify those objects π¦.
the attributes that describe a storage object can include an object label, its type, and its ID π·οΈ. the attributes that identify a PKCS #11 token can include a token label, manufacturer name, serial number, and token model π. slots can be identified with a slot ID, description, and manufacturer πΈ. Cryptoki libraries can be identified with a library manufacturer, description, and version π. library attributes may be necessary if more than one Cryptoki library provides a token and/or PKCS #11 objects with the same name π. there's a set of query attributes too, so you're covered β¨.
a PKCS #11 URI can't identify other objects defined in the specification [PKCS11] besides storage objects π ββοΈ. for example, a hardware feature and a mechanism can't be identified by a PKCS #11 URI π. also, a Cryptoki library doesn't have to provide storage objects at all, and in that case the URI can still be used to identify a specific PKCS #11 token, slot, or an API producer π«Ά.
a subset of existing PKCS #11 structure members and object attributes was picked to uniquely identify a storage object, token, slot, or library π. you can use it in a configuration file, on a command line, or in a configuration property of something else π . if you ever need a more complex information exchange about PKCS #11 entities, a different means of data marshalling should be chosen for that π§ .
a PKCS #11 URI is NOT meant for creating new PKCS #11 objects in tokens or for creating PKCS #11 tokens. it's only for identifying and working with existing storage objects, tokens, and slots through the PKCS #11 API, or for identifying Cryptoki libraries themselves π.
this URI scheme is designed specifically with a mapping to the PKCS #11 API in mind π. it uses the scheme, path, and query components from the "Uniform Resource Identifier (URI): Generic Syntax" [RFC3986] document πΈ. it doesn't use the hierarchical element for a naming authority in the path, because the authority part couldn't be mapped to PKCS #11 API elements π ββοΈ. and it doesn't use the fragment component π«.
if an application has no access to a producer (or producers) of the PKCS #11 API, the query component module attributes can be used β¨. the PKCS #11 URI consumer can always decide to provide its own user interface to locate and load PKCS #11 API producers π.
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 [RFC2119]. π
2. PKCS #11 URI Scheme Definition π
in accordance with [RFC4395], this section gives you all the info you need to register the PKCS #11 URI scheme π.
2.1. PKCS #11 URI Scheme Name π·οΈ
pkcs11
2.2. PKCS #11 URI Scheme Status β
Permanent
2.3. PKCS #11 URI Scheme Syntax π¦
a PKCS #11 URI is a sequence of attribute value pairs separated by a semicolon. they form a one-level path component, and you can optionally add a query π. except for the value of the "id" attribute (more on that later in this section), these attribute value pairs and query components are made entirely of textual data. so they SHOULD all first be encoded as octets using the UTF-8 character encoding [RFC3629], in accordance with Section 2.5 of [RFC3986] π. then, only the octets that don't correspond to characters in the unreserved set, or to permitted characters from the reserved set, SHOULD be percent-encoded π«Ά.
the value of the "id" attribute SHOULD NOT be encoded as UTF-8, because it can contain non-textual data. instead, it SHOULD be entirely percent-encoded π. see the important caveats in Sections 2.5 and 5 about working with UTF-8 strings that have characters outside the US-ASCII character set β οΈ.
the grammar rules "unreserved" and "pct-encoded" in the PKCS #11 URI scheme definition below are imported from [RFC3986] π¦. quick special case: according to Appendix A of [RFC3986], a space MUST be percent-encoded π«§. (heads up, that one's a MUST!)
the PKCS #11 specification puts various limits on attribute values. there's a more restrictive character set for the "serial" attribute, and fixed-size buffers for almost all the others, including the "token", "manufacturer", and "model" attributes π. the PKCS #11 URI scheme syntax doesn't impose those limits itself π ββοΈ. but if a PKCS #11 URI consumer runs into values that the PKCS #11 specification wouldn't accept, it MUST refuse the URI as invalid π«π.
a PKCS #11 URI takes the following form (for an explanation of Augmented BNF, see [RFC5234]):
pk11-URI = "pkcs11:" pk11-path [ "?" pk11-query ]
; Path component and its attributes. Path may be empty.
pk11-path = [ pk11-pattr *(";" pk11-pattr) ]
pk11-pattr = pk11-token / pk11-manuf / pk11-serial /
pk11-model / pk11-lib-manuf /
pk11-lib-ver / pk11-lib-desc /
pk11-object / pk11-type / pk11-id /
pk11-slot-desc / pk11-slot-manuf /
pk11-slot-id / pk11-v-pattr
; Query component and its attributes. Query may be empty.
pk11-qattr = pk11-pin-source / pk11-pin-value /
pk11-module-name / pk11-module-path /
pk11-v-qattr
pk11-query = [ pk11-qattr *("&" pk11-qattr) ]
; Section 2.2 of [RFC3986] mandates all potentially reserved characters
; that do not conflict with actual delimiters of the URI do not have
; to be percent-encoded.
pk11-res-avail = ":" / "[" / "]" / "@" / "!" / "$" /
"'" / "(" / ")" / "*" / "+" / "," / "="
pk11-path-res-avail = pk11-res-avail / "&"
; "/" and "?" in the query component MAY be unencoded but "&" MUST
; be encoded since it functions as a delimiter within the component.
pk11-query-res-avail = pk11-res-avail / "/" / "?" / "|"
pk11-pchar = unreserved / pk11-path-res-avail / pct-encoded
pk11-qchar = unreserved / pk11-query-res-avail / pct-encoded
pk11-token = "token" "=" *pk11-pchar
pk11-manuf = "manufacturer" "=" *pk11-pchar
pk11-serial = "serial" "=" *pk11-pchar
pk11-model = "model" "=" *pk11-pchar
pk11-lib-manuf = "library-manufacturer" "=" *pk11-pchar
pk11-lib-desc = "library-description" "=" *pk11-pchar
pk11-lib-ver = "library-version" "=" 1*DIGIT [ "." 1*DIGIT ]
pk11-object = "object" "=" *pk11-pchar
pk11-type = "type" "=" ( "public" / "private" / "cert" /
"secret-key" / "data" )
pk11-id = "id" "=" *pk11-pchar
pk11-slot-manuf = "slot-manufacturer" "=" *pk11-pchar
pk11-slot-desc = "slot-description" "=" *pk11-pchar
pk11-slot-id = "slot-id" "=" 1*DIGIT
pk11-pin-source = "pin-source" "=" *pk11-qchar
pk11-pin-value = "pin-value" "=" *pk11-qchar
pk11-module-name = "module-name" "=" *pk11-qchar
pk11-module-path = "module-path" "=" *pk11-qchar
pk11-v-attr-nm-char = ALPHA / DIGIT / "-" / "_"
; The permitted value of a vendor-specific attribute is based on
; whether the attribute is used in the path or in the query.
pk11-v-pattr = 1*pk11-v-attr-nm-char "=" *pk11-pchar
pk11-v-qattr = 1*pk11-v-attr-nm-char "=" *pk11-qchar
Okay so the path component is basically where you find the resource itself ποΈ It holds attributes that identify a resource in a one-level hierarchy provided by Cryptoki producers. The query component is the helper squad π«Ά It can hold a few attributes that might be needed to actually retrieve the thing the path points to. Path attributes are separated by the ; character, and query attributes use & as their delimiter. Main character energy for each one, honestly β¨
Both the path and the query components MAY contain vendor-specific attributes π Those attribute names MUST NOT clash with existing attribute names, so no copying someone else's name, periodt. Also, per [BCP178], the older habit of starting vendor attributes with an "x-" prefix is now deprecated π So if you see it in old URIs, it's giving outdated.
Now the delimiters, which are very picky π The general / delimiter MUST be percent-encoded in the path component, so that generic URI parsers never chop the path into multiple segments. It MAY be left unencoded in the query component. The ? delimiter MUST be percent-encoded in the path component, because the PKCS #11 URI scheme uses a query component. The # delimiter MUST always be percent-encoded, so generic URI parsers don't think a hash is the start of a fragment identifier π§ All the other generic delimiters MAY be used unencoded in a PKCS #11 URI: :, [, ], and @ β¨
Next up is the mapping table between the path attributes and the PKCS #11 API structure members and object attributes πΈ PKCS #11 URI users might be pretty new to the PKCS #11 spec, so this mapping is a bit of a compromise between matching the spec names exactly and keeping the URI easy to use and understand π¦
+----------------------+---------------------+----------------------+
| URI component path | Attribute | PKCS #11 |
| attribute name | represents | specification |
| | | counterpart |
+----------------------+---------------------+----------------------+
| id | key identifier for | "CKA_ID" object |
| | object | attribute |
+----------------------+---------------------+----------------------+
| library-description | character-string | "libraryDescription" |
| | description of the | member of CK_INFO |
| | library | structure. It is a |
| | | UTF-8 string. |
+----------------------+---------------------+----------------------+
| library-manufacturer | ID of the Cryptoki | "manufacturerID" |
| | library | member of the |
| | manufacturer | CK_INFO structure. |
| | | It is a UTF-8 |
| | | string. |
+----------------------+---------------------+----------------------+
| library-version | Cryptoki library | "libraryVersion" |
| | version number | member of the |
| | | CK_INFO structure. |
+----------------------+---------------------+----------------------+
| manufacturer | ID of the token | "manufacturerID" |
| | manufacturer | member of |
| | | CK_TOKEN_INFO |
| | | structure. It is a |
| | | UTF-8 string. |
+----------------------+---------------------+----------------------+
| model | token model | "model" member of |
| | | CK_TOKEN_INFO |
| | | structure. It is a |
| | | UTF-8 string. |
+----------------------+---------------------+----------------------+
| object | description (name) | "CKA_LABEL" object |
| | of the object | attribute. It is a |
| | | UTF-8 string. |
+----------------------+---------------------+----------------------+
| serial | character-string | "serialNumber" |
| | serial number of | member of |
| | the token | CK_TOKEN_INFO |
| | | structure. |
+----------------------+---------------------+----------------------+
| slot-description | slot description | "slotDescription" |
| | | member of |
| | | CK_SLOT_INFO |
| | | structure. It is a |
| | | UTF-8 string. |
+----------------------+---------------------+----------------------+
| slot-id | Cryptoki-assigned | decimal number of |
| | value that | "CK_SLOT_ID" type. |
| | identifies a slot | |
+----------------------+---------------------+----------------------+
| slot-manufacturer | ID of the slot | "manufacturerID" |
| | manufacturer | member of |
| | | CK_SLOT_INFO |
| | | structure. It is a |
| | | UTF-8 string. |
+----------------------+---------------------+----------------------+
| token | application-defined | "label" member of |
| | label, assigned | the CK_TOKEN_INFO |
| | during token | structure. It is a |
| | initialization | UTF-8 string. |
+----------------------+---------------------+----------------------+
| type | object class (type) | "CKA_CLASS" object |
| | | attribute. |
+----------------------+---------------------+----------------------+
Table 1: Mapping between URI Path Component Attributes
and PKCS #11 Specification Names
Next is the mapping between the "type" attribute values and the matching PKCS #11 object classes π
+-----------------+-----------------------+
| Attribute value | PKCS #11 object class |
+-----------------+-----------------------+
| cert | CKO_CERTIFICATE |
| data | CKO_DATA |
| private | CKO_PRIVATE_KEY |
| public | CKO_PUBLIC_KEY |
| secret-key | CKO_SECRET_KEY |
+-----------------+-----------------------+
Table 2: Mapping between the "type" Attribute
and PKCS #11 Object Classes
The query attributes are the sidekicks π The "pin-source" attribute says where the application or library should look for the normal user's token PIN. The "pin-value" attribute gives the normal user's PIN value directly, if that's needed. And the "module-name" and "module-path" attributes tweak the default settings for reaching PKCS #11 providers. For the definition of a "normal user", check out [PKCS11] π
Heads up, bestie: the ABNF rules above are a best-effort definition, and this paragraph adds some extra constraints π A PKCS #11 URI MUST NOT contain duplicate attributes of the same name in the URI path component. Basically, each attribute can show up at most once in the path component π Outside of the query attributes defined in this document, duplicate (vendor) attributes MAY be present in the URI query component, and it's up to the URI consumer to decide how to handle those duplicates π«Ά
Last but not least, the id value can hold non-textual data π¦ Earlier in this section it was mentioned that the corresponding PKCS #11 "CKA_ID" object attribute can contain arbitrary binary data, so yeah, text isn't guaranteed here. That's why the whole value of the id attribute SHOULD be percent-encoded π
The library-version attribute is giving major AND minor version vibes π¦ Its format is "M.N". Both numbers are one byte in size (check the libraryVersion member of the CK_INFO structure in [PKCS11] for the deets β¨). The value "M" for the attribute MUST be interpreted as "M" for the major and "0" for the minor version of the library. If the attribute is present, the major version number is REQUIRED. Both "M" and "N" MUST be decimal numbers π’
Okay so Slot ID is a number that Cryptoki assigns itself, and it's not guaranteed to stay the same across PKCS #11 module initializations π Some libraries and modules do give you stable slot identifiers though π§ So when the slot description and manufacturer ID aren't enough to uniquely identify a specific reader, the slot ID MAY be used to make the token identification more precise. In other scenarios, using slot IDs is likely to cause usability issues π
An empty PKCS #11 URI path component attribute that does allow for an empty value matches a corresponding structure member or an object attribute with an empty value. Also, according to the PKCS #11 specification [PKCS11], empty character values in a PKCS #11 API producer must be padded with spaces and should not be NULL terminated πΈ
2.4. PKCS #11 URI Scheme Query Attribute Semantics β¨
An application can always ask for a PIN by any means it decides to π
Plus, so PKCS #11 URIs stay portable, the format and interpretation of the pin-source attribute value is left to be implementation specific. Still, the following rules SHOULD be followed in descending order for the value of the pin-source attribute:
- If the value represents a URI, it SHOULD be treated as an object containing the PIN. That URI may be
file:,https:, another PKCS #11 URI, or something else π - If the value contains
|<absolute-command-path>, the implementation SHOULD read the PIN from the output of an application specified with the absolute path<absolute-command-path>. The|pipe character doesn't have to be percent-encoded in the query component of a PKCS #11 URI π - Interpret the value as needed in an implementation-dependent way.
If a URI contains both pin-source and pin-value query attributes, the URI SHOULD be refused as invalid π«
Use of the pin-value attribute may have security-related consequences. Section 6 should be consulted before this attribute is ever used. Standard percent-encoding rules SHOULD be followed for the attribute value π
A consumer of PKCS #11 URIs MAY accept the query component attributes module-name and module-path to modify the default settings for accessing a PKCS #11 provider or providers π
Processing the URI query module attributes SHOULD follow these rules:
- The attribute
module-nameSHOULD contain a case-insensitive PKCS #11 module name (not a path nor a filename) without system-specific affixes. An affix could be a.soor.DLLsuffix, or alibprefix, for example. Not using system-specific affixes is expected to increase portability of PKCS #11 URIs among different systems π A URI consumer searching for PKCS #11 modules SHOULD use system or application-specific locations to find modules based on the name provided in the attribute. - The attribute
module-pathSHOULD contain a system-specific absolute path to the PKCS #11 module, or a system-specific absolute path to the directory where PKCS #11 modules are located. For security reasons, a URI with a relative path in this attribute SHOULD be rejected π‘οΈ - The URI consumer MAY refuse to accept either of the attributes, or both. If the attribute present in the URI string isn't accepted, a warning message SHOULD be presented to the provider of the URI, and system-specific module locations SHOULD be used β οΈ
- If either of the module attributes is present, only those modules found matching these query attributes SHOULD be used to search for an entity represented by the URI π
- Using the module attributes does not suppress matching of any other URI path component attributes present in a URI.
- The semantics of using both attributes in the same URI string is implementation specific, but such use SHOULD be avoided.
module-nameis preferred overmodule-pathbecause it's system-independent, butmodule-pathmay be more suitable for development and debugging π§βπ» - A URI MUST NOT contain multiple module attributes of the same name π ββοΈ
Use of the module attributes may have security-related consequences. Section 6 should be consulted before these attributes are ever used π₯Ί
The word "module" was chosen over "library" in these query attribute names to avoid confusion with the semantically different library attributes used in the URI path component π
2.5. PKCS #11 URI Matching Guidelines β¨
A PKCS #11 URI can identify PKCS #11 storage objects, tokens, slots, or Cryptoki libraries. Since one URI may identify four different types of entities, the context it's used in may be needed to figure out the type π For example, a URI with only library attributes could represent all objects in all tokens in all Cryptoki libraries it identifies, all tokens in those libraries, or just the libraries themselves.
The following guidelines can help a PKCS #11 URI consumer (for example, an application accepting PKCS #11 URIs) match the URI with the resource it wants π―
- The consumer needs to know whether the URI is meant to identify PKCS #11 storage object(s), token(s), slot(s), or Cryptoki producer(s).
- If the consumer is willing to accept query component module attributes, only those PKCS #11 providers matching these attributes SHOULD be worked with. See Section 2.4 for more information.
- An unrecognized attribute in the URI path component, including a vendor-specific attribute, SHOULD result in an empty set of matched resources. The consumer can consider whether an error message shown to the user is appropriate in that case π
- An unrecognized attribute in the URI query SHOULD be ignored. The consumer can consider whether a warning message shown to the user is appropriate in that case π
- An attribute that isn't present in the URI path component but is known to a consumer matches everything. Each additional attribute present in the URI path component further restricts the selection βοΈ
- Logically, a URI with an empty path component matches everything. For example, if it's used to identify storage objects, it matches all accessible objects in all tokens provided by all relevant PKCS #11 API producers π
- Use of PIN attributes may change the set of storage objects visible to the consumer π
- Besides the query component attributes defined in this document, vendor-specific query attributes may contain further information about how to perform the selection, or other related information π§©
As noted in Section 5, the PKCS #11 specification isn't clear about how to normalize UTF-8-encoded Unicode characters [RFC3629]. That's why it is RECOMMENDED not to use characters outside the US-ASCII character set for labels and names. Those who find they need such characters should be cautious, conservative, and put in extra effort to be sure they know what they're doing, because failing to do so may create both operational and security risks π¨ When matching UTF-8 string-based attributes (see Table 1) with characters outside the US-ASCII repertoire, normalizing all UTF-8 strings before string comparison may be the only safe approach. For example, for objects (keys), a PKCS #11 attribute search template would only contain attributes that are not UTF-8 strings, and then another pass through the returned objects is needed for UTF-8 string comparison after normalization is applied π§
2.6. PKCS #11 URI Comparison β¨
Comparing two URIs is a way of figuring out whether they're equivalent without looking at the actual resource they point to π― The goal is to minimize false negatives while strictly avoiding false positives. When working with UTF-8 strings containing characters outside the US-ASCII character set, see the important caveats in Sections 2.5 and 5 β οΈ
Two PKCS #11 URIs are said to be equal if their URIs, as character strings, are identical as specified in Section 6.2.1 of [RFC3986], or if both of the following rules are fulfilled:
- The set of attributes present in the URI is equal. The ordering of attributes in the URI string isn't significant for the comparison mechanism π
- The values of the respective attributes are equal, based on the rules specified below.
The rules for comparing values of the respective attributes are:
- The values of the path component attributes
library-description,library-manufacturer,manufacturer,model,object,serial,slot-description,slot-manufacturer,token, andtype, plus the query component attributemodule-name, MUST be compared using a simple string comparison, as specified in Section 6.2.1 of [RFC3986], after both case and percent-encoding normalization have been applied as specified in Section 6.2.2 of [RFC3986] π - The value of the attribute
idMUST be compared using simple string comparison after all bytes are percent-encoded using uppercase letters for digits A-F π‘ - The value of the attribute
library-versionMUST be processed as a specific scheme-based normalization permitted by Section 6.2.3 of [RFC3986]. The value MUST be split into a major and minor version, with the character.(dot) serving as the delimiter. Alibrary-versionof"M"MUST be treated as"M"for the major version and"0"for the minor version. Then the resulting minor and major version numbers MUST be compared separately and numerically π’ - The value of the attribute
slot-idMUST be processed as a specific scheme-based normalization permitted by Section 6.2.3 of [RFC3986] and compared numerically π - If the value of
pin-sourcecontains afile:URI or|<absolute-command-path>, it MUST be compared using simple string comparison after the full syntax-based normalization, as specified in Section 6.2.2 of [RFC3986], has been applied. If the value of thepin-sourceattribute is believed to be overloaded, case and percent-encoding normalization SHOULD be applied before the values are compared, but the exact mechanism of comparison is left to the application π§© - The value of the attribute
module-pathMUST be compared using simple string comparison after the full syntax-based normalization, as specified in Section 6.2.2 of [RFC3986], has been applied ποΈ - When comparing vendor-specific attributes, case and percent-encoding normalization, as specified in Section 6.2.2 of [RFC3986], SHOULD be applied before the values are compared, but the exact mechanism of such a comparison is left to the application πΈ
2.7. Generating PKCS #11 URIs β¨
okay so when you're making PKCS #11 URIs for resources, the exact set of attributes you put in is totally context specific π«Ά like, it depends on what you're doing, bestie. A URI-generating app MAY provide a PKCS #11 URI template [RFC6570] support so it can list URIs that get you back to the same resource(s) again, as long as the template actually captured the context it needed π§
3. Examples of PKCS #11 URIs π
this section is the fun part!! π It shows how PKCS #11 token objects, tokens, slots, and libraries can all be identified with the PKCS #11 URI scheme. heads up that some of these examples have line breaks and spaces added so they're easier to read π As specified in Appendix C of [RFC3986], whitespace SHOULD be ignored when extracting the URI. Also, every space that's actually part of a URI is percent-encoded, per Appendix A of [RFC3986] π
An empty PKCS #11 URI might be useful to PKCS #11 consumers. Check out Section 2.5 for what that one means πΈ
pkcs11:
One of the simplest and most useful forms is a PKCS #11 URI that only has an object label and its type π The default token gets used, so the URI doesn't mention it. Just a heads up, when you're specifying public objects, a token PIN may not be required π¦
pkcs11:object=my-pubkey;type=public
When you're specifying a private key, you'd usually reach for the "pin-source" attribute, "pin-value", or some app-specific method π Note that '/' is NOT percent-encoded in the "pin-source" attribute value, since this attribute lives in the query component and not the path component. That means a '?' separates it from the rest of the URI π
pkcs11:object=my-key;type=private?pin-source=file:/etc/token
This one identifies a certificate in the software token π Check out the empty "serial" value, which only matches an empty "serialNumber" member of the "CK_TOKEN_INFO" structure. The "id" value is fully percent-encoded, as recommended π And yes, ',' is in the reserved set, but it doesn't need to be percent-encoded because it doesn't clash with any sub-delimiters being used. The '#' in "The Software PKCS #11 Softtoken" MUST be percent-encoded, no exceptions π«
pkcs11:token=The%20Software%20PKCS%2311%20Softtoken;
manufacturer=Snake%20Oil,%20Inc.;
model=1.0;
object=my-certificate;
type=cert;
id=%69%95%3E%5C%F4%BD%EC%91;
serial=
?pin-source=file:/etc/token_pin
Next up is how to use the "module-name" query attribute π§ So the module lives at /usr/lib/libmypkcs11.so.1. The attribute value is "mypkcs11", which is just the module name, without the full path, the platform-specific "lib" prefix, or the ".so.1" suffix β¨
pkcs11:object=my-sign-key;
type=private
?module-name=mypkcs11
The "module-path" query attribute is up next π¦ It's handy if a user needs to provide the key through a PKCS #11 module on removable media, for example. How the PIN gets obtained to access the private key is left to the application π
pkcs11:object=my-sign-key;
type=private
?module-path=/mnt/libmypkcs11.so.1
When a token is what's expected, you can identify it without naming any PKCS #11 objects π A PIN might still be needed if you're, say, listing every object on the token. Section 6 should be consulted before the "pin-value" attribute is ever used, so read that first, bestie π
pkcs11:token=Software%20PKCS%2311%20softtoken;
manufacturer=Snake%20Oil,%20Inc.
?pin-value=the-pin
When a slot is what's expected, you can identify it without naming any PKCS #11 objects on whatever token might be inserted into it πΈ
pkcs11:slot-description=Sun%20Metaslot
The Cryptoki library on its own can also be identified, with no PKCS #11 token or object involved π
pkcs11:library-manufacturer=Snake%20Oil,%20Inc.;
library-description=Soft%20Token%20Library;
library-version=1.23
This example has a semicolon inside an attribute value, and that means it MUST be percent-encoded π ββοΈ The token value MUST be read as "My token; created by Joe". Lowercase letters MAY be used in the percent-encoding, like in the "id" value below, BUT Sections 2.1 and 6.2.2.1 of [RFC3986] say all percent-encoded characters SHOULD use uppercase hexadecimal digits. Also, if you were comparing the URI string, the algorithm in Section 2.6 explicitly requires uppercase A-F digits in "id" attribute values, so it's not optional, babe π And like Section 2.3 explained, library version "3" MUST be interpreted as "3" for the major version and "0" for the minor version of the library π
pkcs11:token=My%20token%25%20created%20by%20Joe;
library-version=3;
id=%01%02%03%Ba%dd%Ca%fe%04%05%06
If you need to include a literal "%;" substring, both characters MUST be escaped π«Ά The token value MUST be read as "A name with a substring %;".
pkcs11:token=A%20name%20with%20a%20substring%20%25%3B;
object=my-certificate;
type=cert
The next one has a small A with acute in the token name β¨ It MUST be encoded into octets using UTF-8 and then percent-encoded. A small A with acute is U+225 in Unicode, and its UTF-8 encoding is 195 161 in decimal, which is "%C3%A1" in percent-encoding π§ Also see Section 5 for using characters outside the US-ASCII set in labels π
pkcs11:token=Name%20with%20a%20small%20A%20with%20acute:%20%C3%A1;
object=my-certificate;
type=cert
Both the path and query components MAY contain vendor-specific attributes π Attributes in the query component MUST be delimited by '&'.
pkcs11:token=my-token;
object=my-certificate;
type=cert;
vendor-aaa=value-a
?pin-source=file:/etc/token_pin
&vendor-bbb=value-b
4. IANA Considerations πΈ
4.1. URI Scheme Registration π¦
okay so this document moves the "pkcs11" URI scheme from the "Provisional URI Schemes" registry over to the "Permanent URI Schemes" registry π The registration request follows [RFC4395], and here's the whole thing:
URI scheme name: pkcs11
URI scheme status: permanent
URI scheme syntax: Defined in Section 2.3 of [RFC7512].
URI scheme semantics: Defined in Section 1 of [RFC7512].
Encoding considerations: See Sections 2.3 and 5 of [RFC7512].
Applications/protocols that use this URI scheme name: For general
information, see Section 1 of [RFC7512]. A list of known
consumers of the PKCS #11 URI include GnuTLS, Gnome, p11-kit,
Oracle Solaris 11 and higher, OpenSC, OpenConnect, and FreeIPA.
Interoperability considerations: See Section 5 of [RFC7512].
Security considerations: See Section 6 of [RFC7512].
Contact: Jan Pechanec <Jan.Pechanec@Oracle.com>, Darren Moffat
<Darren.Moffat@Oracle.com>
Author/Change Controller: IESG <iesg@ietf.org>
References: [RFC7512]
5. Internationalization Considerations π
Quick vibe check: the PKCS #11 spec doesn't define a canonical form for strings of CK_UTF8CHAR type π€ That means the usual false negative and false positive (aliasing) problems pop up with unnormalized strings. Since all PKCS #11 items are local and local security is assumed, these issues are mostly about usability and interoperability π
To make the user experience better, it is RECOMMENDED that applications creating PKCS #11 objects or labeling tokens don't use characters outside the US-ASCII set for labels π If that's not possible, labels SHOULD be normalized to Normalization Form C (NFC) [UAX15]. For the same reason, PKCS #11 libraries, slots (token readers), and tokens SHOULD use only US-ASCII characters for their names, and if they can't, they SHOULD normalize their names to NFC πΈ When an application lists PKCS #11 libraries, slots, tokens, and/or objects, it SHOULD normalize their names to NFC if characters outside the US-ASCII set are expected π§ When matching PKCS #11 URIs to libraries, slots, tokens, and/or objects, applications MAY convert names to a chosen normalization form before the string comparison, since some of those names might predate these recommendations π«Ά See also Section 2.5.
6. Security Considerations π
this section is SERIOUS, bestie π€ There are general security considerations for URI schemes in Section 7 of [RFC3986], and you need to know them.
From those, Section 7.1 of [RFC3986] applies, because there's no guarantee that the same PKCS #11 URI will always identify the same object, token, slot, or library in the future π
Section 7.2 of [RFC3986] applies too π By accepting the "module-name" or "module-path" query attributes, the consumer could end up loading arbitrary code into a process. Yikes!!
Section 7.5 of [RFC3986] applies as well, since a PKCS #11 URI might show up in world-readable command-line arguments, get stored in public configuration files, or otherwise get used in clear text π For that reason, the "pin-value" attribute should only be used if the URI string itself is protected with the same level of security as the token PIN it goes with π
The PKCS #11 spec doesn't let you authenticate devices to users; it only authenticates users to tokens π ββοΈ So local and physical security are what's really required here. The user must be in possession of their tokens, and the system the tokens are inserted into must be secure π‘οΈ Because of that, the usual normalization security concerns don't come up. For the same reason, confusable script issues don't come up either π Still, if you need characters outside the US-ASCII set, the best move is to normalize all strings in PKCS #11 API elements to NFC. See also Section 5 π«Ά
7. References π
7.1. Normative References π
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997,
<http://www.rfc-editor.org/info/rfc2119>.
[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
10646", STD 63, RFC 3629, November 2003,
<http://www.rfc-editor.org/info/rfc3629>.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66, RFC
3986, January 2005,
<http://www.rfc-editor.org/info/rfc3986>.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234, January 2008,
<http://www.rfc-editor.org/info/rfc5234>.
7.2. Informative References β¨
okay bestie, these are the extra-credit reads ππ§ the stuff that's helpful background but isn't required to actually build the thing:
[BCP178]Saint-Andre, P., Crocker, D., and M. Nottingham, "Deprecating the "X-" Prefix and Similar Constructs in Application Protocols", RFC 6648, BCP 178, June 2012,<http://www.rfc-editor.org/info/bcp178>.[PKCS11]RSA Laboratories, "PKCS #11 v2.20: Cryptographic Token Interface Standard", Public Key Cryptography Standards PKCS#11-v2.20, June 2004.[RFC4395]Hansen, T., Hardie, T., and L. Masinter, "Guidelines and Registration Procedures for New URI Schemes", BCP 35, RFC 4395, February 2006,<http://www.rfc-editor.org/info/rfc4395>.[RFC6570]Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., and D. Orchard, "URI Template", RFC 6570, March 2012,<http://www.rfc-editor.org/info/rfc6570>.[UAX15]Davis, M., Ed. and K. Whistler, Ed., "Unicode Standard Annex #15: Unicode Normalization Forms", Version Unicode 7.0.0, June 2014,<http://unicode.org/reports/tr15/>.
Contributors π«Ά
Stef Walter, Nikos Mavrogiannopoulos, Nico Williams, Dan Winship, Jaroslav Imrich, and Mark Phalan contributed to the development of this document. Shawn Emery shepherded the document. π
Authors' Addresses π
These are the lovely humans who wrote it, so here's where you can find them π¦
Jan Pechanec
Oracle Corporation
4180 Network Circle
Santa Clara, CA 95054
United States
EMail: Jan.Pechanec@Oracle.com
URI: http://www.oracle.com
Darren J. Moffat
Oracle Corporation
Oracle Parkway
Thames Valley Park
Reading RG6 1RA
United Kingdom
EMail: Darren.Moffat@Oracle.com
URI: http://www.oracle.com
π¦ where this page comes from
- ietf: rfc7512 2015-04
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms