RFC 6031

Cryptographic Message Syntax (CMS) Symmetric Key Package Content Type

๐Ÿ“… published December 2010, from ietf

RFC 6031: Cryptographic Message Syntax (CMS) Symmetric Key Package Content Type ๐ŸŽ€

Part 1 of 5 ๐Ÿ’–

Okay bestie, so this is RFC 6031 ๐Ÿฆ‹. S. Turner from IECA and R. Housley from Vigil Security wrote it, and it's a Standards Track doc, which means it's official IETF business ๐Ÿ‘‘. It's ISSN 2070-1721 and it dropped in December 2010 โœจ. The header doesn't list anything it obsoletes or updates, so there's no older version it's replacing or patching ๐Ÿ’….

Abstract ๐ŸŒธ

So this doc defines the symmetric key format content type ๐Ÿ”‘. It's transport independent, which means it doesn't care how it travels ๐Ÿšš. CMS can be used to digitally sign, digest, authenticate, or encrypt this content type โœจ.

Status of This Memo ๐Ÿ“‹

This one 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) ๐Ÿ”ฅ. If you want more on Internet Standards, check out Section 2 of RFC 5741 ๐Ÿ“š.

For the current status, any errata, and how to give feedback, head to http://www.rfc-editor.org/info/rfc6031 ๐Ÿงš.

Copyright (c) 2010 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 in effect on the date of publication. Please read these carefully, because they describe your rights and restrictions for this document ๐Ÿ“œ. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Simplified BSD License ๐Ÿ™ˆ.


Table of Contents ๐Ÿ—‚๏ธ

   1. Introduction...................................................3
      1.1. Requirements Terminology..................................3
      1.2. ASN.1 Syntax Notation.....................................3
   2. Symmetric Key Package Content Type.............................3
   3. PSKC Attributes................................................4
      3.1. PSKC Key Package Attributes...............................5
         3.1.1. Device Information Attributes........................5
         3.1.2. Cryptographic Module Information Attributes..........8
      3.2. PSKC Key Attributes.......................................8
         3.2.1. Key Identifier.......................................8
         3.2.2. Algorithm............................................9
         3.2.3. Issuer...............................................9
         3.2.4. Key Profile Identifier...............................9
         3.2.5. Key Reference Identifier.............................9
         3.2.6. Friendly Name.......................................10
         3.2.7. Algorithm Parameters................................10
         3.2.8. Counter.............................................12
         3.2.9. Time................................................13
         3.2.10. Time Interval......................................13
         3.2.11. Time Drift.........................................13
         3.2.12. Value MAC..........................................13
         3.2.13. Key User Id........................................14
      3.3. Key Policy Attributes....................................14
         3.3.1. Key Start Date......................................14
         3.3.2. Key Expiry Date.....................................15
         3.3.3. Number of Transactions..............................15
         3.3.4. Key Usage...........................................15
         3.3.5. PIN Policy..........................................16
   4. Key Encoding..................................................18
      4.1. AES Key Encoding.........................................18
      4.2. Triple-DES Key Encoding..................................18
   5. Security Considerations.......................................19
   6. IANA Considerations...........................................19
   7. References....................................................19
      7.1. Normative References.....................................19
      7.2. Informative References...................................21
   Appendix A. ASN.1 Module.........................................22
      A.1. Symmetric Key Package ASN.1 Module.......................22
      A.2. PSKC ASN.1 Module........................................23

1. Introduction ๐Ÿฆ‹

So this doc defines the symmetric key format content type, and it's transport independent ๐ŸŒˆ. CMS [RFC5652] can be used to digitally sign, digest, authenticate, or encrypt this content type ๐Ÿ’….

The use cases that inspired the attributes here are explained in [RFC6030]. They're left out so we don't repeat ourselves ๐Ÿ™ˆ.

This document also has ASN.1 definitions for the Extensible Markup Language (XML) elements and attributes defined in [RFC6030] ๐Ÿงš.

1.1. Requirements Terminology ๐ŸŽ€

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] ๐Ÿ”ฅ.

1.2. ASN.1 Syntax Notation ๐Ÿ“

The key package is defined using the ASN.1 in [X.680], [X.681], [X.682], and [X.683] โœจ.

2. Symmetric Key Package Content Type ๐Ÿ”‘

Okay, this is the main event ๐Ÿ‘‘. The symmetric key package content type is used to move one or more plaintext symmetric keys from one party to another. A symmetric key package MAY be wrapped in one or more CMS protecting content types ๐Ÿ’–. This content type MUST be Distinguished Encoding Rules (DER) encoded [X.690] ๐Ÿ”’.

Here's the syntax for the symmetric key package content type ๐Ÿ“ฆ:

     ct-symmetric-key-package CONTENT-TYPE ::=
         { TYPE SymmetricKeyPackage IDENTIFIED BY id-ct-KP-sKeyPackage }

     id-ct-KP-sKeyPackage OBJECT IDENTIFIER ::=
        { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
          smime(16) ct(1) 25 }

     SymmetricKeyPackage ::= SEQUENCE {
       version           KeyPkgVersion DEFAULT v1,
       sKeyPkgAttrs  [0] SEQUENCE SIZE (1..MAX) OF Attribute
                                      {{ SKeyPkgAttributes }} OPTIONAL,
       sKeys             SymmetricKeys,
       ... }

     SymmetricKeys ::= SEQUENCE SIZE (1..MAX) OF OneSymmetricKey

     OneSymmetricKey ::= SEQUENCE {
       sKeyAttrs  SEQUENCE SIZE (1..MAX) OF Attribute
                                      {{ SKeyAttributes }}  OPTIONAL,
       sKey       OCTET STRING OPTIONAL }
       ( WITH COMPONENTS { ..., sKeyAttrs PRESENT } |
         WITH COMPONENTS { ..., sKey PRESENT } )

     KeyPkgVersion ::= INTEGER  { v1(1) } ( v1, ... )

Here's how the SymmetricKeyPackage fields work ๐Ÿง:

  • version tells you which version of the symmetric key package content structure you're looking at. For this version of the spec, the default value, v1, MUST be used ๐Ÿ’….
  • sKeyPkgAttrs is optional and holds attributes that apply to all of the symmetric keys in the package ๐ŸŽ€. The SKeyPkgAttributes information object set limits which attributes are allowed in sKeyPkgAttrs. If an attribute shows up here, then it MUST NOT also be included in sKeyAttrs ๐Ÿ™…โ€โ™€๏ธ.
  • sKeys holds a sequence of OneSymmetricKey values. We'll dig into that structure below ๐Ÿ”.

And here's how the OneSymmetricKey fields work ๐Ÿ—๏ธ:

  • sKeyAttrs is optional and holds attributes that apply to one symmetric key ๐Ÿ’ซ. The SKeyAttributes information object set limits which attributes are permitted in sKeyAttrs. If an attribute shows up here, then it MUST NOT also be included in sKeyPkgAttrs ๐Ÿ™…โ€โ™€๏ธ.
  • sKey is optional and holds the key value, encoded as an OCTET STRING ๐Ÿ”.

The OneSymmetricKey field MUST include sKeyAttrs, sKey, or sKeyAttrs and sKey ๐Ÿซถ.

3. PSKC Attributes ๐ŸŒธ

Okay, this section is where the attributes live ๐Ÿงš. The following attributes help anyone using the symmetric key package from this document as part of a Dynamic Symmetric Key Provision Protocol (DSKPP) [RFC6063] with Portable Symmetric Key Container (PSKC) attributes ๐Ÿ’–. [RFC6030] should be consulted for the definitive attribute descriptions, so go there for the official word ๐Ÿ“š.

The attributes come in three categories ๐ŸŒˆ. The first category covers attributes that apply to a key package, and these will generally show up in sKeyPkgAttrs. The second category covers attributes that apply to a particular key, and these will generally show up in sKeyAttrs. The third category covers attributes that apply to a key policy ๐Ÿ“‹. Out of all the attributes defined, only the Key Identifier (Section 3.2.1) and Algorithm (Section 3.2.2) key attributes MUST be included ๐Ÿ”ฅ. Everything else is OPTIONAL ๐ŸŽ€.

Like PSKC, the Symmetric Key Content Type is extensible ๐Ÿฆ‹. Mostly this happens by defining and including new attributes. But in some cases where an attribute holds more than one type, the ASN.1 "..." extensibility mechanism is used ๐Ÿงฉ.

There's a pretty straightforward way to convert XML types to ASN.1 ๐Ÿ“. <xs:string> becomes UTF8String, <xs:dateTime> becomes GeneralizedTime, and the XML integer types become INTEGER or BinaryTime [RFC6019] โœจ.

3.1. PSKC Key Package Attributes ๐Ÿ’…

PSKC key package attributes apply to an entire key package ๐Ÿ‘‘. They can be sorted into two attribute collections: device information and cryptographic module attributes ๐Ÿ’œ. Every one of these key package attributes is OPTIONAL ๐Ÿซถ.

3.1.1. Device Information Attributes ๐Ÿ“ฑ

Device Information attributes, taken together, MUST uniquely identify the device the Symmetric Key Package is provisioned to ๐Ÿ”ฅ.

3.1.1.1. Manufacturer ๐Ÿญ

The Manufacturer attribute tells you who made the device ๐Ÿ› ๏ธ. Manufacturer values MUST come from either [OATHMAN] prefixes (the left column, i.e., the left column) or the IANA Private Enterprise Number Registry [IANAPENREG], using the Organization value. When the value comes from [OATHMAN], "oath." MUST be prepended to it, like "oath.<values from [OATHMAN]>". When the value comes from [IANAPENREG], "iana." MUST be prepended to it, like "iana.<Organization value from [IANAPENREG]>" ๐ŸŽ€. Here's the attribute definition ๐Ÿงพ:

   at-pskc-manufacturer ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-manufacturer }

   id-pskc-manufacturer OBJECT IDENTIFIER ::= { id-pskc 1 }

3.1.1.2. Serial Number ๐Ÿ”ข

The Serial Number attribute gives the serial number of the device ๐Ÿฆ‹. Here's the attribute definition โœจ:

   at-pskc-serialNo ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-serialNo }

   id-pskc-serialNo OBJECT IDENTIFIER ::= { id-pskc 2 }

3.1.1.3. Model ๐Ÿ“Ÿ

The Model attribute gives the model of the device ๐ŸŒธ. Here's the attribute definition ๐Ÿ’–:

   at-pskc-model ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-model }

   id-pskc-model OBJECT IDENTIFIER ::= { id-pskc 3 }

3.1.1.4. Issue Number ๐Ÿท๏ธ

The Issue Number attribute holds an issue number so you can tell apart two devices that have the same serial number ๐Ÿฅน. Here's the attribute definition ๐Ÿงš:

   at-pskc-issueNo ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-issueNo }

   id-pskc-issueNo OBJECT IDENTIFIER ::= { id-pskc 4 }

3.1.1.5. Device Binding ๐Ÿ”—

okay so Device Binding is an opaque identifier that lets keys get bound to a specific device or to a whole class of devices ๐Ÿฆ‹ it's giving "this key belongs HERE" energy.

When you load keys into a device, the attribute's value MUST be checked against info the user got through out-of-band mechanisms ๐Ÿซถ the implementation then makes sure the right device (or class of device) is being used for the provisioned key. no cap, this is the bouncer check ๐Ÿ’…

   at-pskc-deviceBinding ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-deviceBinding }

   id-pskc-deviceBinding OBJECT IDENTIFIER ::= { id-pskc 5 }

3.1.1.6. Device Start Date ๐ŸŒธ

when this is included in sKeyPkgAttrs, the Device Start Date attribute tells you the start date for a device ๐Ÿ—“๏ธ the date MUST be represented in a form that matches the dateTime production in "canonical representation" [XMLSCHEMA]. implementations SHOULD NOT rely on time resolution finer than milliseconds, and they MUST NOT generate time instants that specify leap seconds ๐Ÿ™ˆ (the leap second drama is real, bestie).

keys on the device SHOULD only be used when the current date is on or after the device start date โœจ the attribute definition looks like this:

   at-pskc-deviceStartDate ATTRIBUTE ::= {
     TYPE GeneralizedTime IDENTIFIED BY id-pskc-deviceStartDate }

   id-pskc-deviceStartDate OBJECT IDENTIFIER ::= { id-pskc 6 }

okay but the lowkey plot twist: usage enforcement of the keys with respect to the dates MAY only happen on the validation server, because some devices (like smart cards) don't have an internal clock ๐Ÿ’€ so systems SHOULD NOT rely upon the device to enforce key usage date restrictions. the device can't be your date-checker if it has no clock, periodt ๐Ÿ™…โ€โ™€๏ธ

3.1.1.7. Device Expiry Date ๐Ÿ“

when this is included in sKeyPkgAttrs, the Device Expiry Date attribute tells you the expiry date for a device โณ same rules as the start date: the date MUST be represented in a form that matches the dateTime production in "canonical representation" [XMLSCHEMA]. implementations SHOULD NOT rely on time resolution finer than milliseconds, and they MUST NOT generate time instants that specify leap seconds ๐Ÿ˜ญ

keys on the device SHOULD only be used when the current date is before the device expiry date ๐Ÿ’œ the attribute definition is below:

   at-pskc-deviceExpiryDate ATTRIBUTE ::= {
     TYPE GeneralizedTime IDENTIFIED BY id-pskc-deviceExpiryDate }

   id-pskc-deviceExpiryDate OBJECT IDENTIFIER ::= { id-pskc 7 }

Note that usage enforcement of the keys with respect to the dates MAY only happen on the validation server, since smart cards and friends don't have an internal clock ๐Ÿงš so systems SHOULD NOT rely upon the device to enforce key usage date restrictions. same tea as the start date, iykyk ๐Ÿซ–

3.1.1.8. Device User Id ๐ŸŽ€

the Device User Id attribute says which user the device is associated with, using a distinguished name as defined in [RFC4514] โœจ for example: UID=jsmith,DC=example,DC=net. the attribute definition is:

   at-pskc-deviceUserId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-deviceUserId }

   id-pskc-deviceUserId OBJECT IDENTIFIER ::= { id-pskc 26 }

as specified in [RFC6030], this element has no semantics attached to it ๐Ÿ™ƒ so there are NO checks enforcing that only one specific user can use the device. it's purely for informational purposes, so don't build a security wall out of it, bestie ๐Ÿšซ

3.1.2. Cryptographic Module Information Attributes ๐Ÿ”

Cryptographic Module attributes uniquely identify a cryptographic module ๐Ÿ’– this is super useful when the device has more than one cryptographic module in it. right now, only one attribute is defined here ๐ŸŒˆ

3.1.2.1. Cryptographic Module Identifier ๐Ÿ’Ž

when this is included in sKeyPkgAttrs, the Cryptographic Module Identifier attribute uniquely identifies the cryptographic module that the key is being (or was) provisioned to ๐Ÿฆ„ the attribute definition is:

   at-pskc-moduleId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-moduleId }

   id-pskc-moduleId OBJECT IDENTIFIER ::= { id-pskc 8 }

3.2. PSKC Key Attributes ๐Ÿ”‘

PSKC key attributes apply to one specific key ๐ŸŽฏ as noted earlier, the Key Identifier (Section 3.2.1) and Algorithm (Section 3.2.2) key attributes are REQUIRED. everything else is OPTIONAL, so you get to pick your extras ๐Ÿ’…

3.2.1. Key Identifier ๐Ÿชช

when this is included in sKeyAttrs, the Key Identifier attribute identifies the key during key provisioning exchanges between two parties ๐Ÿค this is the big one: if PSKC gets used across multiple interactions between a sending and receiving party, with different containers pointing at the same keys, the KeyId MUST use the same KeyId values. for example, after initial provisioning, if a system wants to update key metadata on the other system, the KeyId value of the key being updated MUST be the same as the original KeyId value that was provisioned ๐Ÿ“Œ no swapping IDs mid-friendship, okay? ๐Ÿ˜ค

the attribute definition is:

   at-pskc-keyId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-keyId }

   id-pskc-keyId OBJECT IDENTIFIER ::= { id-pskc 9 }

3.2.2. Algorithm ๐Ÿงฎ

the Algorithm attribute uniquely identifies the PSKC algorithm profile โœจ [RFC6030] defines two algorithm profiles: "HOTP" and "PIN" ๐Ÿ”ข the attribute definition is:

   at-pskc-algorithm ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-algorithm }

   id-pskc-algorithm OBJECT IDENTIFIER ::= { id-pskc 10 }

3.2.3. Issuer ๐Ÿ›๏ธ

the Issuer attribute names the entity that issued the key ๐Ÿซก the attribute definition is:

   at-pskc-issuer ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-issuer }

   id-pskc-issuer OBJECT IDENTIFIER ::= { id-pskc 11 }

3.2.4. Key Profile Identifier ๐Ÿช„

the Key Profile Identifier attribute carries a unique identifier that the sending and receiving parties use to agree on a set of key attribute values ๐Ÿคซ those values are NOT sent inside the container. instead, they're agreed on out of band between the two parties ๐Ÿ“ฌ this attribute then acts as the unique reference to that set of key attribute values, so it's basically a secret handshake ๐Ÿ˜Œ

   at-pskc-keyProfileId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-keyProfileId }

   id-pskc-keyProfileId OBJECT IDENTIFIER ::= { id-pskc 12 }

3.2.5. Key Reference Identifier ๐Ÿ—๏ธ

the Key Reference attribute points at an external key that's used with a key derivation scheme ๐Ÿง  no actual key value (secret) gets transported here. only the reference to the external master key is sent, like a PKCS #11 key label ๐Ÿท๏ธ very "I know where the keys are, I don't need to carry them around" energy ๐Ÿ’…

   at-pskc-keyReference ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-keyReference }

   id-pskc-keyReference OBJECT IDENTIFIER ::= { id-pskc 13 }

3.2.6. Friendly Name ๐ŸŒท

the Friendly Name attribute holds a human-readable name for the secret key ๐Ÿฅฐ the attribute definition is:

   at-pskc-friendlyName ATTRIBUTE ::= {
     TYPE FriendlyName IDENTIFIED BY id-pskc-friendlyName }

   id-pskc-friendlyName OBJECT IDENTIFIER ::= { id-pskc 14 }

the Friendly Name attribute has this syntax:

   FriendlyName ::= SEQUENCE {
     friendlyName        UTF8String,
     friendlyNameLangTag UTF8String OPTIONAL }

the text is encoded in UTF-8 [RFC3629], which means it can handle pretty much every writing system in the world ๐ŸŒโœจ the friendlyNameLangTag field tells you which language the friendlyName is written in. if that field is absent, English is assumed, with the language tag "en" ๐Ÿ‡ฌ๐Ÿ‡ง and when the friendlyNameLangTag field IS present, its value MUST be a language tag, as described in [RFC5646] ๐Ÿณ๏ธโ€๐ŸŒˆ that's the vibe check for this part, bestie ๐Ÿ‘‘

3.2.7. Algorithm Parameters โœจ

okay so the Algorithm Parameters attribute is where the extra knobs live ๐ŸŽ›๏ธ they tweak the math an algorithm does, like how a response gets truncated and what format it comes out in, for One-Time Password (OTP) and Challenge/Response (CR) algorithms. it's giving precision ๐Ÿ’…

   at-pskc-algorithmParameters ATTRIBUTE ::= {
     TYPE PSKCAlgorithmParameters
     IDENTIFIED BY id-pskc-algorithmParams }

   id-pskc-algorithmParams OBJECT IDENTIFIER ::= { id-pskc 15 }

the attribute has this syntax, bestie ๐Ÿ‘‘

   PSKCAlgorithmParameters ::= CHOICE {
     suite                UTF8String,
     challengeFormat  [0] ChallengeFormat,
     responseFormat   [1] ResponseFormat,
     ... }

   ChallengeFormat ::= SEQUENCE {
     encoding    Encoding,
     checkDigit  BOOLEAN DEFAULT FALSE,
     min         INTEGER (0..MAX),
     max         INTEGER (0..MAX),
     ... }

   Encoding ::= UTF8STRING ("DECIMAL" | "HEXADECIMAL" |
                "ALPHANUMERIC" |"BASE64" |"BINARY")

   ResponseFormat ::= SEQUENCE {
     encoding     Encoding,
     length       INTEGER (0..MAX),
     checkDigit   BOOLEAN DEFAULT FALSE,
     ... }

okay the fields in PSKCAlgorithmParameters, lowkey the important bit ๐Ÿซถ

  • suite defines extra characteristics of the algorithm, and they're algorithm specific. like, in an HMAC-based (Hashed Message Authentication Code) OTP algorithm it could say how strong the hash is (SHA1, SHA256, etc.). for the exact semantics of each value for each algorithm profile, go check the algorithm profile specification [RFC6030] ๐Ÿ“š
  • ChallengeFormat defines the challenge in a CR usage scenario, and it has these fields:
    • encoding specifies the encoding of the challenge the device accepts, and it MUST be one of these values: DECIMAL, HEXADECIMAL, ALPHANUMERIC, BASE64, or BINARY. BASE64 is done as in Section 4 of [RFC4648] ๐ŸŒธ
    • checkDigit says whether a device needs to check the appended Luhn check digit (as defined in [ISOIEC7812]) inside a challenge. the checkDigit MUST NOT be present if the encoding value is anything other than 'DECIMAL'. TRUE means the device WILL check the appended Luhn check digit in a provided challenge, and FALSE means it won't ๐Ÿ™ˆ
    • min is the minimum size of the challenge the device accepts for CR mode. for 'DECIMAL', 'HEXADECIMAL', or 'ALPHANUMERIC' that's the minimum number of digits/characters, and for 'BASE64' or 'BINARY' it's the minimum number of bytes of the unencoded value ๐Ÿงš
    • max is the maximum size of the challenge the device accepts for CR mode, counted the same way as min ๐Ÿ“
  • ResponseFormat defines the characteristics of the result of a computation, so it's the format of the OTP or the response to a challenge. when the key is a personal identification number (PIN) value, this element holds the format of the PIN itself (like DECIMAL, length 4 for a 4 digit PIN) ๐Ÿ”ข its fields are:
    • encoding specifies the encoding of the response the device generates, and it MUST be one of these values: DECIMAL, HEXADECIMAL, ALPHANUMERIC, BASE64, or BINARY. BASE64 is defined as in Section 4 of [RFC4648] ๐Ÿ’œ
    • length defines the length of the response the device generates. for 'DECIMAL', 'HEXADECIMAL', or 'ALPHANUMERIC' that's the number of digits/characters, and for 'BASE64' or 'BINARY' it's the number of bytes of the unencoded value โœจ
    • checkDigit says whether the device needs to append a Luhn check digit (as defined in [ISOIEC7812]) to the response. this is only valid if the encoding is 'DECIMAL'. TRUE means the device WILL append it, and FALSE means it won't ๐Ÿฆ‹

3.2.8. Counter

the Counter attribute holds the event counter for event-based OTP algorithms ๐ŸŽ€ here's how it's defined:

   at-pskc-counter ATTRIBUTE ::= {
     TYPE INTEGER(0..MAX) IDENTIFIED BY id-pskc-counter }

   id-pskc-counter OBJECT IDENTIFIER ::= { id-pskc 16 }

3.2.9. Time

the Time attribute conveys the time for time-based OTP algorithms โฐ if the Time Interval attribute is included, then this element carries the number of time intervals that have passed for a specific start point. and if the time interval is used, it carries the number of intervals passed from a specific start point, which is normally algorithm dependent ๐Ÿ•ฐ๏ธ it uses the BinaryTime syntax from [RFC6019]. defined like so:

   at-pskc-time ATTRIBUTE ::= {
     TYPE BinaryTime IDENTIFIED BY id-pskc-time }

   id-pskc-time OBJECT IDENTIFIER ::= { id-pskc 17 }

3.2.10. Time Interval

the Time Interval attribute conveys the time interval for time-based OTP algorithms, in seconds. so a value of 30 means a 30 second interval ๐ŸŒˆ it's an integer, and it's defined as:

   at-pskc-timeInterval ATTRIBUTE ::= {
     TYPE INTEGER (0..MAX) IDENTIFIED BY id-pskc-timeInterval }

   id-pskc-timeInterval OBJECT IDENTIFIER ::= { id-pskc 18 }

3.2.11. Time Drift

the Time Drift attribute holds the device clock drift value for time-based OTP algorithms ๐Ÿ•’ it's an integer, positive or negative, showing how many time intervals a validation server has worked out that the device clock drifted since the last successful authentication. the definition:

   at-pskc-timeDrift ATTRIBUTE ::= {
     TYPE INTEGER (0..MAX) IDENTIFIED BY id-pskc-timeDrift }

   id-pskc-timeDrift OBJECT IDENTIFIER ::= { id-pskc 19 }

3.2.12. Value MAC

the Value MAC attribute is a Message Authentication Code (MAC) generated from the encrypted value, for when the encryption algorithm doesn't support integrity checks ๐Ÿ” like, AES-CBC doesn't give you integrity, but AES Key Wrap with a message length indicator (MLI) does ๐Ÿ™Œ here's the attribute definition:

   at-pskc-valueMAC ATTRIBUTE ::= {
     TYPE ValueMac IDENTIFIED BY id-pskc-valueMAC }

   id-pskc-valueMAC OBJECT IDENTIFIER ::= { id-pskc 20 }

   ValueMac ::= SEQUENCE {
     macAlgorithm UTF8String,
     mac          UTF8String }

the fields in ValueMac:

  • macAlgorithm identifies the MAC algorithm used to generate the value placed in digest. ๐Ÿงพ
  • mac is the base64-encoded mac value, as specified in Section 4 of [RFC4648] ๐Ÿฌ

3.2.13. Key User Id

the Key User Id attribute says which user the key is associated with, using a distinguished name as defined in [RFC4514]. for example, UID=jsmith,DC=example,DC=net ๐Ÿชช the definition is:

   at-pskc-keyUserId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-keyUserId }

   id-pskc-keyUserId OBJECT IDENTIFIER ::= { id-pskc 27 }
okay real talk, as specified in [RFC6030] this one has no semantics attached. there are NO checks enforcing that only a specific user can use the key ๐Ÿšจ so it's informational only, not a security guarantee, babe.

3.3. Key Policy Attributes

okay so key policy attributes are the rules you can attach to a key ๐Ÿ“œ they're defined in the subsections below, and they're giving boundaries ๐Ÿšง

3.3.1. Key Start Date

when it's included in sKeyAttrs, the Key Start Date attribute marks the start of the key's validity period ๐ŸŒ… the date MUST be represented in a form that matches the dateTime production in "canonical representation" [XMLSCHEMA]. implementations SHOULD NOT rely on time resolution finer than milliseconds, and they MUST NOT generate time instants that specify leap seconds โณ the definition:

   at-pskc-keyStartDate ATTRIBUTE ::= {
       TYPE GeneralizedTime IDENTIFIED BY id-pskc-keyStartDate }

   id-pskc-keyStartDate OBJECT IDENTIFIER ::= { id-pskc 21 }

3.3.2. Key Expiry Date

when it's included in sKeyAttrs, the Key Expiry Date attribute marks the end of the key's validity period ๐ŸŒ‡ the date MUST be represented in a form that matches the dateTime production in "canonical representation" [XMLSCHEMA]. implementations SHOULD NOT rely on time resolution finer than milliseconds, and they MUST NOT generate time instants that specify leap seconds ๐Ÿ’€ the definition:

   at-pskc-keyExpiryDate ATTRIBUTE ::= {
     TYPE GeneralizedTime IDENTIFIED BY id-pskc-keyExpiryDate }

   id-pskc-keyExpiryDate OBJECT IDENTIFIER ::= { id-pskc 22 }

3.3.3. Number of Transactions

the Number of Transactions attribute caps how many times a key carried in the package can be used ๐Ÿ” if this element is omitted, there's no restriction on how many times the key can be used. the definition:

   at-pskc-noOfTransactions ATTRIBUTE ::= {
     TYPE INTEGER (0..MAX) IDENTIFIED BY id-pskc-noOfTransactions }

   id-pskc-noOfTransactions OBJECT IDENTIFIER ::= { id-pskc 23 }

3.3.4. Key Usage

the Key Usage attribute constrains what the key is intended to be used for ๐ŸŽฏ the recipient MUST enforce the key usage, no exceptions, periodt ๐Ÿ’… the definition:

   at-pskc-keyUsage ATTRIBUTE ::= {
     TYPE PSKCKeyUsages IDENTIFIED BY id-pskc-keyUsages }

   id-pskc-keyUsages OBJECT IDENTIFIER ::= { id-pskc 24 }

   PSKCKeyUsages ::= SEQUENCE OF PSKCKeyUsage

   PSKCKeyUsage ::= UTF8String ("OTP" | "CR" | "Encrypt" |
                    "Integrity" | "Verify" | "Unlock" | "Decrypt" |
                    "KeyWrap" | "Unwrap" | "Derive" | "Generate")

the fields in PSKCKeyUsage, one by one because each one is its own whole vibe โœจ

  • OTP: The key MUST only be used for OTP generation. ๐Ÿ”ข
  • CR: The key MUST only be used for Challenge/Response purposes. ๐Ÿ”
  • Encrypt: The key MUST only be used for data encryption purposes. ๐Ÿ”’
  • Integrity: The key MUST only be used to generate a keyed message digest for data integrity or authentication purposes. ๐Ÿ›ก๏ธ
  • Verify: The key MUST only be used to verify a keyed message digest for data integrity or authentication purposes (it's the converse of Integrity). โœ…
  • Unlock: The key MUST only be used for an inverse Challenge/Response in the case in which a user has locked the device by entering an incorrect PIN too many times (for devices with PIN-input capability). ๐Ÿ”“
  • Decrypt: The key MUST only be used for data decryption purposes. ๐Ÿ—๏ธ
  • KeyWrap: The key MUST only be used for key wrap purposes. ๐ŸŽ
  • Unwrap: The key MUST only be used for key unwrap purposes. ๐Ÿ“ฆ
  • Derive: The key MUST only be used with a key derivation function to derive a new key (see also Section 8.2.4 of [NIST800-57]). ๐Ÿงช
  • Generate: The key MUST only be used to generate a new key based on a random number and the previous value of the key (see also Section 8.1.5.2.1 of [NIST800-57]). ๐ŸŒŸ

3.3.5. PIN Policy

okay so the PIN Policy attribute is basically the bouncer ๐Ÿ’… ๐ŸŽ€ it lets you attach rules about how the PIN gets used to the key itself. here's the definition:

at-pskc-pinPolicy ATTRIBUTE ::= {
  TYPE PINPolicy IDENTIFIED BY id-pskc-pinPolicy }

id-pskc-pinPolicy OBJECT IDENTIFIER ::= { id-pskc 25 }
PINPolicy ::= SEQUENCE {
  pinKeyId          [0] UTF8String OPTIONAL,
  pinUsageMode      [1] PINUsageMode,
  maxFailedAttempts [2] INTEGER (0..MAX) OPTIONAL,
  minLength         [3] INTEGER (0..MAX) OPTIONAL,
  maxLength         [4] INTEGER (0..MAX) OPTIONAL,
  pinEncoding       [5] Encoding OPTIONAL }

PINUsageMode ::= UTF8String ("Local" | "Prepend" | "Append" |
                 "Algorithmic")

so here's what each field means ๐Ÿฆ‹

  • pinKeyId uniquely identifies the key held within this container that contains the value of the PIN that protects the key. it's like the key's ID card ๐Ÿชช
  • pinUsageMode indicates the way the PIN is used during the usage of the key. the values defined in [RFC6030] are Local, Prepend, Append, and Algorithmic. ๐ŸŒธ
  • maxFailedAttempts indicates the maximum number of times the PIN may be entered incorrectly before it MUST NOT be possible to use the key anymore. reasonable values are in the positive integer range of at least 2 and no more than 10. ๐Ÿ’€ too many wrong guesses and the key is locked, periodt
  • minLength indicates the minimum length of a PIN that can be set to protect the associated key. it MUST NOT be possible to set a PIN shorter than this value. if pinEncoding is 'DECIMAL', 'HEXADECIMAL', or 'ALPHANUMERIC', this value counts digits/characters. if pinEncoding is 'BASE64' or 'BINARY', this value counts the bytes of the unencoded value. โœจ
  • maxLength indicates the maximum length of a PIN that can be set to protect this key. it MUST NOT be possible to set a PIN longer than this value. if the pinEncoding is 'DECIMAL', 'HEXADECIMAL', or 'ALPHANUMERIC', this value counts digits/characters. if the pinEncoding is 'BASE64' or 'BINARY', this value counts the bytes of the unencoded value. ๐Ÿ“
  • pinEncoding is based on Encoding, which is defined in Section 3.2.7. it specifies the encoding of the PIN and MUST be one of the following values: DECIMAL, HEXADECIMAL, ALPHANUMERIC, BASE64, or BINARY. ๐Ÿซถ

now the big bestie moment: if pinUsageMode is set to "Local", then the device MUST enforce the restriction indicated in maxFailedAttempts, minLength, maxLength, and pinEncoding. otherwise, it MUST be enforced on the server side. ๐Ÿ‘‘ the device or the server is the one doing the policing, depending on the mode, and that's the whole plot ๐Ÿ”ฅ


4. Key Encoding โœจ

okay this part is so important, bestie ๐Ÿฅน two parties getting the same key as an sKey OCTET STRING have to use it in exactly the same way or they just won't interoperate. so we need a clear correspondence between the abstract syntax of sKey and the notation the standard algorithm description uses to say how the key gets used. the next sections set that up for the AES algorithm [FIPS197] and the Triple Data Encryption Algorithm (TDEA or Triple DES) [SP800-67]. ๐Ÿ’œ

4.1. AES Key Encoding

so [FIPS197], Section 5.2, which is titled "Key Expansion", treats the input key as an array of bytes indexed starting at 0. the first octet of sKey SHALL become the key byte in the AES, labeled index 0 in [FIPS197]. the succeeding octets of sKey SHALL become key bytes in AES, in increasing index order. ๐ŸŒˆ

proper parsing and key load of the sKey contents for AES SHALL be determined by using the following sKey OCTET STRING to generate and match the key expansion test vectors in [FIPS197], Appendix A, for AES Cipher Key: 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c ๐Ÿงš

  Tag Length Value
  04  16     2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c

4.2. Triple-DES Key Encoding

a Triple-DES key is made up of three keys for the cryptographic engine (Key1, Key2, and Key3). each one is 64 bits, which is 56 key bits plus 8 parity bits. the three keys are also collectively called a key bundle [SP800-67]. a key bundle may use either two or three independent keys. when only two independent keys are used (called two-key Triple DES), the same value is used for Key1 and Key3. ๐Ÿฆ‹

each key in a Triple-DES key bundle gets expanded into a key schedule following a procedure defined in [SP800-67], Appendix A. that procedure numbers the bits in the key from 1 to 64, with number 1 being the leftmost, or most significant bit (MSB). the first octet of sKey SHALL be bits 1 through 8 of Key1, with bit 1 being the MSB. the second octet of sKey SHALL be bits 9 through 16 of Key1, and so on, so that the trailing octet of sKey SHALL be bits 57 through 64 of Key3 (or Key2 for two-key Triple DES). ๐ŸŽ€

proper parsing and key load of the sKey contents for Triple DES SHALL be determined by using the following sKey OCTET STRING to generate and match the key expansion test vectors in [SP800-67], Appendix B, for the key bundle:

Key1 = 0123456789ABCDEF

Key2 = 23456789ABCDEF01

Key3 = 456789ABCDEF0123
  Tag Length Value
  04  24     0123456789ABCDEF 23456789ABCDEF01 456789ABCDEF0123

5. Security Considerations ๐Ÿ”

okay, security time, and it's serious ๐Ÿ˜ญ implementers of this protocol are strongly encouraged to consider generally accepted principles of secure key management when integrating this capability into an overall security architecture. no shortcuts, bestie.

the symmetric key package contents are NOT protected ๐Ÿ’€ this content type can be combined with a security protocol to protect the contents of the package. one option is to include this content type in place of a PSKC package in [RFC6063] exchanges, and then the algorithm requirements live in those documents. another option is to wrap this content type in a CMS [RFC5652] protecting content type. โœจ


6. IANA Considerations ๐ŸŒธ

this document uses object identifiers to identify a CMS content type (Appendix A.1), the ASN.1 version of the PSKC attributes (Appendix A.2), and the ASN.1 modules found in Appendix A.1 and A.2. ๐Ÿงš

all OIDs are registered in an arc delegated by RSADSI to the SMIME Working Group. ๐Ÿ‘‘


7. References ๐Ÿ“š

7.1. Normative References

  • [FIPS197]: National Institute of Standards. "FIPS Pub 197: Advanced Encryption Standard (AES)", 26 November 2001.
  • [IANAPENREG]: IANA, "Private Enterprise Numbers", <http://www.iana.org>.
  • [ISOIEC7812]: ISO, "ISO/IEC 7812-1:2006 Identification cards -- Identification of issuers -- Part 1: Numbering system", October 2006, <http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=39698>.
  • [OATHMAN]: OATH, "List of OATH Manufacturer Prefixes (omp)", April 2009, <http://www.openauthentication.org/oath-id/prefixes>.
  • [RFC2119]: Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC3629]: Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003.
  • [RFC4514]: Zeilenga, K., Ed., "Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names", RFC 4514, June 2006.
  • [RFC4648]: Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, October 2006.
  • [RFC5646]: Phillips, A., Ed., and M. Davis, Ed., "Tags for Identifying Languages", BCP 47, RFC 5646, September 2009.
  • [RFC5911]: Hoffman, P. and J. Schaad, "New ASN.1 Modules for Cryptographic Message Syntax (CMS) and S/MIME", RFC 5911, June 2010.
  • [RFC5912]: Hoffman, P. and J. Schaad, "New ASN.1 Modules for the Public Key Infrastructure Using X.509 (PKIX)", RFC 5912, June 2010.
  • [RFC6019]: Housley, R., "BinaryTime: An Alternate Format for Representing Date and Time in ASN.1", RFC 6019, September 2010.
  • [RFC6030]: Hoyer, P., Pei, M., and S. Machani, "Portable Symmetric Key Container (PSKC)", RFC 6030, October 2010.
  • [SP800-67]: National Institute of Standards and Technology, "NIST Special Publication 800-67 Version 1.1: Recommendation for the Triple Data Encryption Algorithm (TDEA) Block Cipher", NIST Special Publication 800-67, May 2008.
  • [X.680]: ITU-T Recommendation X.680 (2002) | ISO/IEC 8824-1:2002. Information Technology - Abstract Syntax Notation One.
  • [X.681]: ITU-T Recommendation X.681 (2002) | ISO/IEC 8824-2:2002. Information Technology - Abstract Syntax Notation One: Information Object Specification.
  • [X.682]: ITU-T Recommendation X.682 (2002) | ISO/IEC 8824-3:2002. Information Technology - Abstract Syntax Notation One: Constraint Specification.
  • [X.683]: ITU-T Recommendation X.683 (2002) | ISO/IEC 8824-4:2002. Information Technology - Abstract Syntax Notation One: Parameterization of ASN.1 Specifications.
  • [X.690]: ITU-T Recommendation X.690 (2002) | ISO/IEC 8825-1:2002. Information Technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER).
  • [XMLSCHEMA]: Malhotra, A. and P. Biron, "XML Schema Part 2: Datatypes Second Edition", World Wide Web Consortium Recommendation REC-xmlschema-2-20041082, October 2004, <http://www.w3.org/TR/2004/REC-xmlschema-2-20041028>.

7.2. Informative References

  • [NIST800-57]: National Institute of Standards and Technology, "NIST Special Publication 800-57, Recommendation for Key Management - Part 1: General (Revised)", NIST Special Publication 800-57, March 2007.
  • [RFC5652]: Housley, R., "Cryptographic Message Syntax (CMS)", STD 70, RFC 5652, September 2009.
  • [RFC6063]: Doherty, A., Pei, M., Machani, S., and M. Nystrom, "Dynamic Symmetric Key Provisioning Protocol (DSKPP)", RFC 6063, December 2010.

Appendix A. ASN.1 Module ๐ŸŽ€

this appendix gives the normative ASN.1 definitions for the structures described in this specification, using ASN.1 as defined in [X.680], [X.681], [X.682], and [X.683]. โœจ

A.1. Symmetric Key Package ASN.1 Module โœจ

okay so this is the ASN.1 module for the symmetric key package ๐Ÿ’– it's giving very organised energy ๐ŸŽ€

   SymmetricKeyPackageModulev1
     { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
       smime(16) modules(0) id-mod-symmetricKeyPkgV1(33) }

   DEFINITIONS IMPLICIT TAGS ::=

   BEGIN

   -- EXPORTS ALL

   IMPORTS

   -- From New PKIX ASN.1 [RFC5912]

   ATTRIBUTE
     FROM PKIX-CommonTypes-2009
      { iso(1) identified-organization(3) dod(6) internet(1)
        security(5) mechanisms(5) pkix(7) id-mod(0)
        id-mod-pkixCommon-02(57) }

   -- From New SMIME ASN.1 [RFC5911]

   CONTENT-TYPE, Attribute{}
     FROM CryptographicMessageSyntax-2009
       { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
         smime(16) modules(0) id-mod-cms-2004-02(41) }

   ;

    ContentSet CONTENT-TYPE ::= {
       ct-symmetric-key-package,
       ... -- Expect additional content types --
     }

     ct-symmetric-key-package CONTENT-TYPE ::=
       { TYPE SymmetricKeyPackage IDENTIFIED BY id-ct-KP-sKeyPackage }

     id-ct-KP-sKeyPackage OBJECT IDENTIFIER ::=
       { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
         smime(16) ct(1) 25 }

     SymmetricKeyPackage ::= SEQUENCE {
       version           KeyPkgVersion DEFAULT v1,
       sKeyPkgAttrs  [0] SEQUENCE SIZE (1..MAX) OF Attribute
                                      {{ SKeyPkgAttributes }} OPTIONAL,
       sKeys             SymmetricKeys,
       ... }

     SymmetricKeys ::= SEQUENCE SIZE (1..MAX) OF OneSymmetricKey

     OneSymmetricKey ::= SEQUENCE {
       sKeyAttrs  SEQUENCE SIZE (1..MAX) OF Attribute
                                         {{ SKeyAttributes }} OPTIONAL,
       sKey       OCTET STRING OPTIONAL }
       ( WITH COMPONENTS { ..., sKeyAttrs PRESENT } |
         WITH COMPONENTS { ..., sKey PRESENT } )

     KeyPkgVersion ::= INTEGER  { v1(1) } ( v1, ... )

     SKeyPkgAttributes ATTRIBUTE ::= { ... }

     SKeyAttributes ATTRIBUTE ::= { ... }

   END

A.2. PSKC ASN.1 Module ๐Ÿฆ‹

this one is the PSKC module, and it's absolutely packed with attributes, bestie ๐Ÿ˜ญ๐Ÿซถ

   PSKCAttributesModule
     { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
       smime(16) modules(0) id-mod-pskcAttributesModule(53) }

   DEFINITIONS IMPLICIT TAGS ::=

   BEGIN

   -- EXPORTS ALL

   IMPORTS

   -- From New PKIX ASN.1 [RFC5912]

   ATTRIBUTE
     FROM PKIX-CommonTypes-2009
      { iso(1) identified-organization(3) dod(6) internet(1)
        security(5) mechanisms(5) pkix(7) id-mod(0)
        id-mod-pkixCommon-02(57) }

   -- From BinaryTime [RFC6019]

   BinaryTime
     FROM BinarySigningTimeModule
       { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
         smime(16) modules(0) id-mod-binarySigningTime(27) }

   -- From New SMIME ASN.1 [RFC5911]

   id-smime
     FROM SecureMimeMessageV3dot1-2009
       { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
         smime(16) modules(0) id-mod-msg-v3dot1-02(39) }

   ;

   --
   -- PSKC Attributes OIDs are taken from the SMIME Arc.
   --

   id-pskc OBJECT IDENTIFIER ::= { id-smime 12 }

   --
   -- Merge SKeyPKGAttributes to the set of attributes for sKeyPkgAttrs
   --

   SKeyPkgAttributes ATTRIBUTE ::= {
     at-pskc-manufacturer | at-pskc-serialNo | at-pskc-model |
     at-pskc-issueNo | at-pskc-deviceBinding |
     at-pskc-deviceStartDate | at-pskc-deviceExpiryDate |
     at-pskc-moduleId | at-pskc-deviceUserId, ... }

   --
   -- Merge SKeyAttributes to the set of attributes for sKeyAttrs
   --

   SKeyAttributes ATTRIBUTE ::= {
     at-pskc-keyId | at-pskc-algorithm | at-pskc-issuer |
     at-pskc-keyProfileId | at-pskc-keyReference |
     at-pskc-friendlyName | at-pskc-algorithmParameters |
     at-pskc-counter | at-pskc-time | at-pskc-timeInterval |
     at-pskc-timeDrift | at-pskc-valueMAC | at-pskc-keyUserId  |
     at-pskc-keyStartDate | at-pskc-keyExpiryDate |
     at-pskc-numberOfTransactions | at-pskc-keyUsage |
     at-pskc-pinPolicy, ... }

   at-pskc-manufacturer ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-manufacturer }

   id-pskc-manufacturer OBJECT IDENTIFIER ::= { id-pskc 1 }

   at-pskc-serialNo ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-serialNo }

   id-pskc-serialNo OBJECT IDENTIFIER ::= { id-pskc 2 }

   at-pskc-model ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-model }

   id-pskc-model OBJECT IDENTIFIER ::= { id-pskc 3 }

   at-pskc-issueNo ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-issueNo }

   id-pskc-issueNo OBJECT IDENTIFIER ::= { id-pskc 4 }

   at-pskc-deviceBinding ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-deviceBinding }

   id-pskc-deviceBinding OBJECT IDENTIFIER ::= { id-pskc 5 }

   at-pskc-deviceStartDate ATTRIBUTE ::= {
     TYPE GeneralizedTime IDENTIFIED BY id-pskc-deviceStartDate }

   id-pskc-deviceStartDate OBJECT IDENTIFIER ::= { id-pskc 6 }

   at-pskc-deviceExpiryDate ATTRIBUTE ::= {
     TYPE GeneralizedTime IDENTIFIED BY id-pskc-deviceExpiryDate }

   id-pskc-deviceExpiryDate OBJECT IDENTIFIER ::= { id-pskc 7 }

   at-pskc-moduleId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-moduleId }

   id-pskc-moduleId OBJECT IDENTIFIER ::= { id-pskc 8 }

   at-pskc-deviceUserId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-deviceUserId }

   id-pskc-deviceUserId OBJECT IDENTIFIER ::= { id-pskc 26 }

   at-pskc-keyId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-keyId }

   id-pskc-keyId OBJECT IDENTIFIER ::= { id-pskc 9 }
   at-pskc-algorithm ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-algorithm }

   id-pskc-algorithm OBJECT IDENTIFIER ::= { id-pskc 10 }

   at-pskc-issuer ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-issuer }

   id-pskc-issuer OBJECT IDENTIFIER ::= { id-pskc 11 }

   at-pskc-keyProfileId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-keyProfileId }

   id-pskc-keyProfileId OBJECT IDENTIFIER ::= { id-pskc 12 }

   at-pskc-keyReference ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-keyReference }

   id-pskc-keyReference OBJECT IDENTIFIER ::= { id-pskc 13 }

   at-pskc-friendlyName ATTRIBUTE ::= {
     TYPE FriendlyName IDENTIFIED BY id-pskc-friendlyName }

   id-pskc-friendlyName OBJECT IDENTIFIER ::= { id-pskc 14 }

   FriendlyName ::= SEQUENCE {
     friendlyName        UTF8String,
     friendlyNameLangTag UTF8String OPTIONAL }

   at-pskc-algorithmParameters ATTRIBUTE ::= {
     TYPE PSKCAlgorithmParameters
     IDENTIFIED BY id-pskc-algorithmParameters }

   id-pskc-algorithmParameters OBJECT IDENTIFIER ::= { id-pskc 15 }

   PSKCAlgorithmParameters ::= CHOICE {
     suite                UTF8String,
     challengeFormat  [0] ChallengeFormat,
     responseFormat   [1] ResponseFormat,
     ... }

   ChallengeFormat ::= SEQUENCE {
     encoding    Encoding,
     checkDigit  BOOLEAN DEFAULT FALSE,
     min         INTEGER (0..MAX),
     max         INTEGER (0..MAX),
     ... }

   Encoding ::= UTF8String ("DECIMAL" | "HEXADECIMAL" |
                "ALPHANUMERIC" | "BASE64" | "BINARY" )

   ResponseFormat ::= SEQUENCE {
     encoding     Encoding,
     length       INTEGER (0..MAX),
     checkDigit   BOOLEAN DEFAULT FALSE,
     ... }

   at-pskc-counter ATTRIBUTE ::= {
     TYPE INTEGER (0..MAX) IDENTIFIED BY id-pskc-counter }

   id-pskc-counter OBJECT IDENTIFIER ::= { id-pskc 16 }

   at-pskc-time ATTRIBUTE ::= {
     TYPE BinaryTime IDENTIFIED BY id-pskc-time }

   id-pskc-time OBJECT IDENTIFIER ::= { id-pskc 17 }

   at-pskc-timeInterval ATTRIBUTE ::= {
     TYPE INTEGER (0..MAX) IDENTIFIED BY id-pskc-timeInterval }

   id-pskc-timeInterval OBJECT IDENTIFIER ::= { id-pskc 18 }

   at-pskc-timeDrift ATTRIBUTE ::= {
     TYPE INTEGER (0..MAX) IDENTIFIED BY id-pskc-timeDrift }

   id-pskc-timeDrift OBJECT IDENTIFIER ::= { id-pskc 19 }

   at-pskc-valueMAC ATTRIBUTE ::= {
     TYPE ValueMac IDENTIFIED BY id-pskc-valueMAC }

   id-pskc-valueMAC OBJECT IDENTIFIER ::= { id-pskc 20 }

   ValueMac ::= SEQUENCE {
     macAlgorithm UTF8String,
     mac          UTF8String }

   at-pskc-keyUserId ATTRIBUTE ::= {
     TYPE UTF8String IDENTIFIED BY id-pskc-keyUserId }

   id-pskc-keyUserId OBJECT IDENTIFIER ::= { id-pskc 27 }

   at-pskc-keyStartDate ATTRIBUTE ::= {
     TYPE GeneralizedTime IDENTIFIED BY id-pskc-keyStartDate }

   id-pskc-keyStartDate OBJECT IDENTIFIER ::= { id-pskc 21 }
   at-pskc-keyExpiryDate ATTRIBUTE ::= {
     TYPE GeneralizedTime IDENTIFIED BY id-pskc-keyExpiryDate }

   id-pskc-keyExpiryDate OBJECT IDENTIFIER ::= { id-pskc 22 }

   at-pskc-numberOfTransactions ATTRIBUTE ::= {
     TYPE INTEGER (0..MAX) IDENTIFIED BY id-pskc-numberOfTransactions }

   id-pskc-numberOfTransactions OBJECT IDENTIFIER ::= { id-pskc 23 }

   at-pskc-keyUsage ATTRIBUTE ::= {
     TYPE PSKCKeyUsages IDENTIFIED BY id-pskc-keyUsages }

   id-pskc-keyUsages OBJECT IDENTIFIER ::= { id-pskc 24 }

   PSKCKeyUsages ::= SEQUENCE OF PSKCKeyUsage

   PSKCKeyUsage ::= UTF8String ("OTP" | "CR" | "Encrypt" |
                    "Integrity" | "Verify" | "Unlock" | "Decrypt" |
                    "KeyWrap" | "Unwrap" | "Derive" | "Generate")

   at-pskc-pinPolicy ATTRIBUTE ::= {
     TYPE PINPolicy IDENTIFIED BY id-pskc-pinPolicy }

   id-pskc-pinPolicy OBJECT IDENTIFIER ::= { id-pskc 25 }

   PINPolicy ::= SEQUENCE {
     pinKeyId          [0] UTF8String OPTIONAL,
     pinUsageMode      [1] PINUsageMode,
     maxFailedAttempts [2] INTEGER (0..MAX) OPTIONAL,
     minLength         [3] INTEGER (0..MAX) OPTIONAL,
     maxLength         [4] INTEGER (0..MAX) OPTIONAL,
     pinEncoding       [5] Encoding OPTIONAL }

   PINUsageMode ::= UTF8String ("Local" | "Prepend" | "Append"|
                    "Algorithmic")

   END

Authors' Addresses ๐Ÿ’œ

the authors, the legends who wrote this whole thing ๐Ÿ‘‘

   Sean Turner
   IECA, Inc.
   3057 Nutley Street, Suite 106
   Fairfax, VA 22031
   USA

   EMail: turners@ieca.com


   Russell Housley
   Vigil Security, LLC
   918 Spring Knoll Drive
   Herndon, VA 20170
   USA

   EMail: housley@vigilsec.com

that's the whole thing, bestie ๐ŸŒˆ๐Ÿฆ‹โœจ

๐Ÿ“ฆ where this page comes from