RFC 7906

NSA's Cryptographic Message Syntax (CMS) Key Management Attributes

πŸ“… published June 2016, from ietf

NSA's Cryptographic Message Syntax (CMS) Key Management Attributes πŸŽ€

RFC 7906, published June 2016, is an Independent Submission with a category of Informational (ISSN 2070-1721). The authors are P. Timmel from the National Security Agency, R. Housley from Vigil Security, and S. Turner from IECA. The title block doesn't list anything it obsoletes or updates. It does update several information object sets from RFC 6268, RFC 5958, and RFC 6031, which Section 1.1 explains. πŸ’–

Abstract ✨

This doc defines key management attributes that the National Security Agency (NSA) uses. The attributes can show up in asymmetric and/or symmetric key packages, and also in the CMS content types that wrap those key packages. Key packages from RFC 5958 and RFC 6031 are examples of where you'd use them. πŸ”‘

Status of This Memo 🌸

This doc is not an Internet Standards Track spec. It's published just for information. πŸ“š

It's a contribution to the RFC Series, separate from any other RFC stream. The RFC Editor chose to publish it at their discretion, and they don't say anything about whether it's good to implement or deploy. Docs the RFC Editor approves aren't candidates for any level of Internet Standard. See Section 2 of RFC 7841 for that. 🧐

For the current status, any errata, and how to give feedback, check http://www.rfc-editor.org/info/rfc7906. πŸ¦‹

Copyright (c) 2016 IETF Trust and the persons identified as the document authors. All rights reserved. ©️

This doc 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 read those carefully, since they spell out your rights and restrictions for this doc. πŸ“œ


Table of Contents πŸ—ΊοΈ

   1. Introduction ....................................................3
      1.1. Attribute Locations ........................................3
      1.2. ASN.1 Notation .............................................4
      1.3. Terminology ................................................5
   2. CMS-Defined Attributes ..........................................6
   3. Community Identifiers ...........................................7
   4. Key Province Attribute ..........................................8
   5. Binary Signing Time .............................................8
   6. Manifest ........................................................9
   7. Key Algorithm ...................................................9
   8. User Certificate ...............................................11
   9. Key Package Receivers ..........................................11
   10. TSEC Nomenclature .............................................13
   11. Key Purpose ...................................................16
   12. Key Use .......................................................17
   13. Transport Key .................................................20
   14. Key Distribution Period .......................................20
   15. Key Validity Period ...........................................22
   16. Key Duration ..................................................23
   17. Classification ................................................24
      17.1. Security Label ...........................................25
   18. Split Key Identifier ..........................................29
   19. Key Package Type ..............................................30
   20. Signature Usage ...............................................30
   21. Other Certificate Format ......................................33
   22. PKI Path ......................................................34
   23. Useful Certificates ...........................................35
   24. Key Wrap Algorithm ............................................35
   25. Content Decryption Key Identifier .............................36
      25.1. Content Decryption Key Identifier: Symmetric Key
            and Symmetric ............................................36
      25.2. Content Decryption Key Identifier: Unprotected ...........37
   26. Certificate Pointers ..........................................37
   27. CRL Pointers ..................................................38
   28. Key Package Identifier and Receipt Request ....................38
   29. Additional Error Codes ........................................39
   30. Processing Key Package Attribute Values and CMS
       Content Constraints ...........................................39
   31. Attribute Scope ...............................................41
   32. Security Considerations .......................................48
   33. References ....................................................48
      33.1. Normative References .....................................48
      33.2. Informative References ...................................51
   Appendix A. ASN.1 Module ..........................................52
   Authors' Addresses ................................................68

1. Introduction ✨

This doc defines key management attributes that the National Security Agency (NSA) uses. The attributes can appear in asymmetric and/or symmetric key packages, and also in the Cryptographic Message Syntax (CMS) content types that wrap those key packages. πŸ”

This doc has definitions for brand-new attributes and for attributes that were already defined. For the older ones we point you to where they're defined, but we also include their definitions here so you don't have to hunt them down. 🧚

CMS lets you nest content types in pretty much any way you like. Attributes can also live in lots of different spots inside content types and key packages, which are content types themselves (see Section 1.1). Supporting every single possibility would be extremely complex, so it's not realistic. Instead, some devices may just pick one or more templates, which is a profile for a combo of CMS content type(s), key package, and attribute(s). See Section 19 for more on that. πŸ’…

1.1. Attribute Locations πŸŽ€

A bunch of CMS content types support attributes: SignedData [RFC5652], EnvelopedData [RFC5652], EncryptedData [RFC5652], AuthenticatedData [RFC5652], and AuthEnvelopedData [RFC5083], plus ContentWithAttributes [RFC4073]. There are also other content types defined with CONTENT-TYPE [RFC6268] that support attributes too, including AsymmetricKeyPackage [RFC5958] and SymmetricKeyPackage [RFC6031]. 🌷

CMS sorts its "protecting content types" (SignedData [RFC5652], EnvelopedData [RFC5652], EncryptedData [RFC5652], AuthenticatedData [RFC5652], and AuthEnvelopedData [RFC5083]) as the ones that give you some kind of security service. Then there are the other CMS content types, Data [RFC5652], ContentWithAttributes [RFC4073], and ContentCollection [RFC4073], which give you no security service at all. πŸ›‘οΈ

Those content types also have different kinds of attributes:

  • SignedData has two kinds: signed and unsigned attributes, living in the signedAttrs and unsignedAttrs fields.
  • EnvelopedData and EncryptedData each have just one kind: unprotected attributes in the unprotectedAttrs field.
  • AuthEnvelopedData has two kinds: authenticated and unauthenticated attributes, in the authAttrs and unauthAttrs fields. Both are also unprotected (meaning they're not encrypted), so when we talk about AuthEnvelopedData attributes they're authenticated&unprotected and unauthenticated&unprotected. For this spec, unauthenticated attributes MUST NOT be included. 🚫
  • AuthenticatedData has two kinds too: authenticated and unauthenticated attributes, in the authAttrs and unauthAttrs fields. For this spec, unauthenticated attributes MUST NOT be included. πŸ™…β€β™€οΈ
  • ContentWithAttributes has one kind: content attributes, in the attrs field.
  • AsymmetricKeyPackage has one kind: asymmetric key attributes, in the attributes field. If an attribute shows up as part of an asymmetric key package, it SHOULD appear in the attributes field of the AsymmetricKeyPackage. ✨
  • SymmetricKeyPackage has two kinds: symmetric key and symmetric key package attributes, in the sKeyAttrs and sKeyPkgAttrs fields. Heads up: [RFC6031] doesn't allow the same attribute to show up in both places inside the same SymmetricKeyPackage. πŸ™ˆ

Also, this spec updates a bunch of information object sets so they limit where attributes can go. The ones it updates from [RFC6268] are SignedAttributesSet, UnsignedAttributes, UnprotectedEnvAttributes, UnprotectedEncAttributes, AuthAttributeSet, UnauthAttributeSet, AuthEnvDataAttributeSet, UnauthEnvDataAttributeSet, and ContentAttributeSet. From [RFC5958] it updates OneAsymmetricKeyAttributes, and from [RFC6031] it updates SKeyPkgAttributes and SKeyAttributes. See Appendix A for the ASN.1 for those object sets. 🧩

1.2. ASN.1 Notation πŸ’…

The attributes in this doc use 2002 ASN.1 [X.680] [X.681] [X.682] [X.683]. The attributes MUST be DER [X.690] encoded. 🧾

Each attribute has exactly one attribute value instance in its values set. Even though the syntax is defined as a set, there MUST be exactly one instance of AttributeValue present. Also, SignedAttributes, UnsignedAttributes, UnprotectedAttributes, AuthAttributes, and UnauthAttributes are defined as sets too, and each of those sets MUST include only one instance of any particular type of attribute. In other words, any object identifier that appears in AttributeType MUST only appear one time in the set of attributes. πŸ”

SignedData, EnvelopedData, EncryptedData, AuthenticatedData, AuthEnvelopedData, and ContentWithAttributes were originally written in the 1988 version of ASN.1. [RFC6268] updated them to the 2008 version. None of the new 2008 ASN.1 tokens are used here, which means 2002 compilers can still compile 2008 ASN.1. AsymmetricKeyPackage and SymmetricKeyPackage are defined in 2002 ASN.1. 🌸

[RFC5652] and [RFC2634] define generally useful CMS attributes in the 1988 version of ASN.1. [RFC6268] updated those to the 2008 version (for [RFC5652]), and [RFC5911] updated them to the 2002 version (for [RFC2634]). [RFC4108] and [RFC6019] also defined attributes in the 1988 version, and this doc uses those. [RFC5911] updated both of them to 2002 ASN.1. For the attribute semantics, look at [RFC2634], [RFC4108], [RFC5652], and [RFC6019]. For the attribute's ASN.1 syntax, look at [RFC5911] or [RFC6268]. 🫢

1.3. Terminology

okay so bestie, let's get into the vocab πŸ“šβœ¨ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119]. πŸ’…

Attribute Scope: The scope of an attribute is the compilation of keying material to which the attribute value is assigned. The scope of each attribute is determined by its placement within the key package or content collection. See Section 31. πŸŽ€

SIR: Source Intermediary Receiver is a model with three entities: 🧚

o A source initiates the delivery of a key to one or more receivers. It MAY wrap or encrypt the key for delivery. This is expected to be the common case, since a cleartext key is vulnerable to exposure and compromise. 😭 If the sender is to encrypt the key for delivery, it MUST know how to encrypt the key so that the receiver(s) can decrypt it. A sender MAY also carry out any of the functions of an intermediary. 🫢

  • The original key package creators are sometimes referred to as key source authorities. These entities create the symmetric and/or asymmetric key package and apply the initial CMS protecting layer, which is normally a SignedData but sometimes an AuthenticatedData. This initial CMS protecting layer is maintained through any intermediary for the receivers of the key package to ensure that receivers can validate the key source authority. πŸ‘‘

o An intermediary does not have access to the cleartext key. An intermediary MAY perform source authentication on key packages and MAY append or remove management information related to the package. It MAY encapsulate the encrypted key packages in larger packages that contain other user data destined for later intermediaries or receivers. 🌸

o A receiver has access to the cleartext key. If the received key package is encrypted, it can unwrap or decrypt the encrypted key to obtain the cleartext key. A receiver MAY be the final destination of the cryptographic product. An element that acts as a receiver and is not the final destination of the key package MAY also act as a sender or as an intermediary. After receiving a key, a receiver MAY encrypt the received key for local storage. πŸ¦‹

NOTE: As noted in Section 1, a receiver can be tailored to support a particular combination of CMS content type(s), key package, and attribute(s) resulting in less-complex implementations. All of these tailored receivers can be supported by a common key management infrastructure that uses this specification; this also can yield efficiencies in generation and provisioning. Senders and intermediaries that have to understand multiple tailored receivers get the efficiency of a common specification language and modular implementation, as opposed to needing stove-piped processing for each different receiver. πŸ’–


2. CMS-Defined Attributes ✨

The following attributes are defined for [RFC5652]: 🌈

o content-type [RFC5652] [RFC5911] [RFC6268] uniquely specifies the CMS content type. This attribute MUST be included as a signed, authenticated, or authenticated&unprotected attribute. πŸ”₯

o message-digest [RFC5652] [RFC5911] [RFC6268] is the message digest of the encapsulated content calculated using the signer's message digest algorithm. As specified in [RFC5652], it must be included as a signed attribute and an authenticated attribute; as specified in [RFC5652], it must not be an unsigned attribute, unauthenticated attribute, or unprotected attribute; as specified in [RFC5083], it should not be included as an authenticated&unprotected attribute in AuthEnvelopedData. This attribute MUST NOT be included elsewhere. πŸ™ˆ

o content-hints [RFC2634] [RFC5911] [RFC6268] identifies the innermost content when multiple layers of encapsulation have been applied. Every instance of SignedData, AuthenticatedData, and AuthEnvelopedData that does not directly encapsulate a SymmetricKeyPackage, an AsymmetricKeyPackage, or an EncryptedKeyPackage [RFC6032] MUST include this attribute. πŸ’œ


3. Community Identifiers ✨

The community-identifiers attribute, defined in [RFC4108] and [RFC5911], lists the communities that are authorized recipients of the signed content. It can appear as a signed, authenticated, authenticated&unprotected, or content attribute. This attribute MUST be supported. 🫢

The 2002 ASN.1 syntax for the community-identifiers attribute is included for convenience:

  aa-communityIdentifiers ATTRIBUTE ::= {
    TYPE CommunityIdentifiers
    IDENTIFIED BY id-aa-communityIdentifiers }

  id-aa-communityIdentifiers OBJECT IDENTIFIER ::= {
    iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
    smime(16) aa(2) 40 }

  CommunityIdentifiers ::= SEQUENCE OF CommunityIdentifier

  CommunityIdentifier ::= CHOICE {
    communityOID  OBJECT IDENTIFIER,
    hwModuleList  HardwareModules }

  HardwareModules ::= SEQUENCE {
    hwType           OBJECT IDENTIFIER,
    hwSerialEntries  SEQUENCE OF HardwareSerialEntry }

  HardwareSerialEntry ::= CHOICE {
    all    NULL,
    single OCTET STRING,
    block  SEQUENCE {
             low OCTET STRING,
             high OCTET STRING } }

Consult [RFC4108] for the attribute's semantics. 🧠


4. Key Province Attribute ✨

The key-province-v2 attribute identifies the scope, range, or jurisdiction in which the key is to be used. The key-province-v2 attribute MUST be present as a signed attribute or an authenticated attribute in the innermost CMS protection content type that provides authentication (i.e., SignedData, AuthEnvelopedData, or AuthenticatedData) and encapsulates a symmetric key package or an asymmetric key package. πŸ—ΊοΈ

The key-province attribute has the following syntax:

  aa-keyProvince-v2 ATTRIBUTE ::= {
    TYPE KeyProvinceV2
    IDENTIFIED BY id-aa-KP-keyProvinceV2 }

  id-aa-KP-keyProvinceV2 OBJECT IDENTIFIER ::=
    { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
      dod(2) infosec(1) attributes(5) 71 }

  KeyProvinceV2 ::= OBJECT IDENTIFIER

5. Binary Signing Time ✨

The binary-signing-time attribute, defined in [RFC6019] and [RFC6268], specifies the time at which the signature or the Message Authentication Code (MAC) was applied to the encapsulated content. It can appear as a signed, authenticated, or authenticated&unprotected attribute. ⏰

The 2002 ASN.1 syntax is included for convenience:

  aa-binarySigningTime ATTRIBUTE ::= {
    TYPE BinarySigningTime
    IDENTIFIED BY id-aa-binarySigningTime }

  id-aa-binarySigningTime OBJECT IDENTIFIER ::= {
    iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
    smime(16) aa(2) 46 }

  BinarySigningTime ::= BinaryTime

  BinaryTime ::= INTEGER (0..MAX)

Consult [RFC6019] for the binary-signing-time attribute's semantics. πŸ¦‹


6. Manifest ✨

The manifest attribute lists the short titles of all the Transmission Security Nomenclature (TSEC-Nomenclature) attributes from inner key packages. It MUST only appear as an outermost signed, authenticated, or authenticated&unprotected attribute. If a short title is repeated in inner packages, it need only appear once in the manifest attribute. The manifest attribute MUST NOT appear in the same level as the TSEC-Nomenclature from Section 10. πŸ“‹

The manifest attribute has the following syntax:

  aa-manifest ATTRIBUTE ::= {
    TYPE Manifest
    IDENTIFIED BY id-aa-KP-manifest }

  id-aa-KP-manifest OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1)
    gov(101) dod(2) infosec(1) attributes(5) 72 }

  Manifest ::= SEQUENCE SIZE (1..MAX) OF ShortTitle

7. Key Algorithm πŸ”‘

okay so the key-algorithm attribute is basically how you find out the size and format of the keying material in the skey field of a symmetric key package, which is defined in [RFC6031] πŸ’…. it can show up as a symmetric key, symmetric key package, signed, authenticated, authenticated&unprotected, or content attribute ✨. if it's a signed attribute, all the keying material inside the SignedData content MUST be associated with the same algorithm 🫢. same deal for authenticated or authenticated&unprotected, where all the keying material inside the AuthenticatedData or AuthEnvelopedData content type MUST be associated with the same algorithm. if it's a content attribute, all the keying material in the collection MUST be associated with the same algorithm. if both the key-wrap-algorithm (Section 24) and key-algorithm attributes apply to an sKey, then key-algorithm is talking about the decrypted value of sKey, not the content of sKey itself. this attribute MUST be supported πŸ’–

the key-algorithm attribute has the following syntax:

  aa-keyAlgorithm ATTRIBUTE ::= {
    TYPE KeyAlgorithm
    IDENTIFIED BY id-kma-keyAlgorithm }

  id-kma-keyAlgorithm OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1)
    gov(101) dod(2) infosec(1) keying-material-attributes(13) 1 }

  KeyAlgorithm ::= SEQUENCE {
    keyAlg            OBJECT IDENTIFIER,
    checkWordAlg  [1] OBJECT IDENTIFIER OPTIONAL,
    crcAlg        [2] OBJECT IDENTIFIER OPTIONAL }

the fields in here have the following semantics πŸŽ€

  • keyAlg specifies the size and format of the keying material.
  • if the particular key format supports more than one check-word algorithm, then the OPTIONAL checkWordAlg identifier tells you which check-word algorithm was used to make the check word that's actually present. if the check-word algorithm is implied by the key algorithm, then the checkWordAlg field SHOULD be omitted.
  • if the particular key format supports more than one Cyclic Redundancy Check (CRC) algorithm, then the OPTIONAL crcAlg identifier tells you which CRC algorithm was used to make the value that's present. if the CRC algorithm is implied by the key algorithm, then the crcAlg field SHOULD be omitted.

the keyAlg, checkWordAlg, and crcAlg identifiers are all object identifiers, and using an object identifier means any algorithm from any registry can fit in 🌈

the format of the keying material in the skey field of a symmetric key package will not match this attribute if the keying material is split (see Section 18 for a discussion of the split-identifier attribute). in that situation, this attribute identifies the format of the keying material once the two splits are combined 🧚

because of multiple layers of encapsulation or the use of content collections, the key-algorithm attribute can show up in more than one location in the overall key package. when there are multiple occurrences of the key-algorithm attribute within the same scope, the keyAlg field MUST match in all instances. the OPTIONAL checkWordAlg and crcAlg fields can be left out of the key-algorithm attribute when it appears as a signed, authenticated, authenticated&unprotected, or content attribute. however, if those optional fields are present, they MUST also match the other occurrences within the same scope. receivers MUST reject any key package that fails these consistency checks 🚫


8. User Certificate πŸͺͺ

the user-certificate attribute specifies the type, format, and value of an X.509 certificate, and it's used in an asymmetric key package's attributes field πŸ¦‹ it can appear as an asymmetric key attribute. this attribute MUST NOT appear in an asymmetric key package attributes field that includes the other-certificate-formats attribute. symmetric key packages don't contain any certificates, so the user-certificate attribute MUST NOT appear in a symmetric key package. it also MUST NOT appear as a signed, authenticated, authenticated&unprotected, or content attribute. this attribute MUST be supported πŸ’…

the syntax is taken from [X.509] but redefined using the ATTRIBUTE CLASS from [RFC5912]. the user-certificate attribute has the following syntax:

  aa-userCertificate ATTRIBUTE ::= {
    TYPE Certificate
    EQUALITY MATCHING RULE certificateExactMatch
    IDENTIFIED BY id-at-userCertificate }

  id-at-userCertificate OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) ds(5) attributes(4) 36 }

since the user-certificate attribute MUST NOT appear as a signed, authenticated, authenticated&unprotected, or content attribute, an asymmetric key package can't include multiple occurrences of the user-certificate attribute within the same scope. receivers MUST reject any asymmetric key package in which the user-certificate attribute appears as a signed, authenticated, authenticated&unprotected, or content attribute πŸ™ˆ


9. Key Package Receivers πŸ“¬

the key-package-receivers-v2 attribute tells you who the key package is meant for πŸŽ€ it is not intended for access control decisions. instead, intermediate systems may use it to make routing and relaying decisions 🌸 if the receiver isn't listed, they won't be able to decrypt the package, so the receiver SHOULD reject the key package if the key-package-receivers-v2 attribute is present and they're not listed as an intended receiver 😭 the key-package-receivers-v2 attribute can be used as a signed, authenticated, authenticated&unprotected, or content attribute. if it's associated with a collection, then the named receivers MUST be able to receive all of the key packages within the collection. this attribute MUST be supported ✨

the key-package-receivers-v2 attribute has the following syntax:

  aa-keyPackageReceivers-v2 ATTRIBUTE ::= {
    TYPE KeyPkgReceiversV2
    IDENTIFIED BY id-kma-keyPkgReceiversV2 }

  id-kma-keyPkgReceiversV2 OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 16 }

  KeyPkgReceiversV2 ::= SEQUENCE SIZE (1..MAX) OF KeyPkgReceiver

  KeyPkgReceiver ::= CHOICE {
    sirEntity  [0] SIREntityName,
    community  [1] CommunityIdentifier }

the key-package-receivers-v2 attribute holds a list of receiver identifiers πŸ’œ each receiver identifier is either a SIREntityName [RFC7191] or a CommunityIdentifier (see Section 3). the SIREntityName syntax doesn't impose any particular structure on the receiver identifier, but it does require registration of receiver identifier types. the nameType makes sure that two receiver identifiers of different types that contain the same values aren't treated as equivalent 🫢 name types are expected to be defined at several different granularities. for example, one name type will represent the receiver organization. at a finer granularity, a name type will identify a specific cryptographic device, perhaps using a manufacturer identifier and serial number πŸ”

if a receiver doesn't recognize a particular nameType or a community identifier, then keying material within the scope of that unrecognized nameType or community identifier MUST NOT be used in any manner. however, the receiver doesn't need to discard the associated key package. since lots of cryptographic devices are programmable, a different firmware load may recognize the nameType. likewise, a change in configuration may lead to recognizing a community identifier that used to be unrecognized. so the receiver may keep the key package but refuse to use it for anything with a firmware load that doesn't recognize the nameType, or a configuration that doesn't recognize the community identifier 🌈

whenever a key package is saved for later processing because of an unrecognized nameType or community identifier, subsequent processing MUST NOT rely on any checks that were made the first time the key package processing was tried. that is, the subsequent processing MUST include the full complement of checks. further, a receipt for the packages MUST NOT be generated unless all of these checks are successfully completed 🧾

because of multiple layers of encapsulation or the use of content collections, the key-package-receivers-v2 attribute can show up in more than one location in the overall key package. when that happens, each occurrence is evaluated independently πŸ¦‹

in a content collection, each member of the collection might contain its own signed, authenticated, authenticated&unprotected, or content attribute that includes a key-package-receivers-v2 attribute. in this situation, each member of the collection is evaluated separately, and any member that includes an acceptable receiver SHOULD be retained. other members can be rejected or kept for later processing with a different firmware load πŸ’–

10. TSEC Nomenclature πŸŽ€

Okay bestie, so the TSEC Nomenclature attribute is basically the name tag for a piece of keying material 🏷️✨ Every name tag ALWAYS includes a printable string called a "short title" (more on that in a sec) πŸ’– But sometimes the short title isn't enough to uniquely name the keys, so this attribute can also carry other identifiers to help 🫢 It can show up as a symmetric key, symmetric key package, asymmetric key, signed, authenticated, authenticated&unprotected, or content attribute πŸ¦‹

Now the rules, and they're serious 😭 If it shows up in the sKeyAttrs field, then editionID, registerID, and segmentID MUST NOT be ranges πŸ™…β€β™€οΈ If it's a signed, authenticated, authenticated&unprotected, or content attribute, all the keying material inside the associated content MUST have the same shortTitle, and the attribute value MUST contain only a shortTitle. Like, literally just the short title, so all of the optional fields MUST be absent πŸ’€ If it's tied to a collection, all the keying material in that collection MUST have the same shortTitle, BUT the editionID, registerID, and segmentID will be different for each key package in the collection ✨ And this attribute MUST be supported πŸ‘‘ no skipping!

The TSEC-Nomenclature attribute has the following syntax πŸ“œ

  aa-tsecNomenclature ATTRIBUTE ::= {
    TYPE TSECNomenclature
    IDENTIFIED BY id-kma-TSECNomenclature }

  id-kma-TSECNomenclature OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 3 }

  TSECNomenclature ::= SEQUENCE {
    shortTitle  ShortTitle,
    editionID   EditionID OPTIONAL,
    registerID  RegisterID OPTIONAL,
    segmentID   SegmentID OPTIONAL }

  ShortTitle ::= PrintableString

  EditionID ::= CHOICE {
    char CHOICE {
        charEdition       [1] CharEdition,
        charEditionRange  [2] CharEditionRange }
    num CHOICE {
        numEdition        [3] NumEdition,
        numEditionRange   [4] NumEditionRange } }

  CharEdition ::= PrintableString

  CharEditionRange ::= SEQUENCE {
    firstCharEdition  CharEdition,
    lastCharEdition   CharEdition }

  NumEdition ::= INTEGER (0..308915776)

  NumEditionRange ::= SEQUENCE {
    firstNumEdition  NumEdition,
    lastNumEdition   NumEdition }

  RegisterID ::= CHOICE {
    register       [5] Register,
    registerRange  [6] RegisterRange }

  Register ::= INTEGER (0..2147483647)

  RegisterRange ::= SEQUENCE {
    firstRegister  Register,
    lastRegister   Register }

  SegmentID ::= CHOICE {
    segmentNumber  [7] SegmentNumber,
    segmentRange   [8] SegmentRange }

  SegmentNumber ::= INTEGER (1..127)

  SegmentRange ::= SEQUENCE {
    firstSegment  SegmentNumber,
    lastSegment   SegmentNumber }

Here's what each field means πŸ“

  • The shortTitle consists of up to 32 alphanumeric characters. shortTitle processing always uses the value in its entirety. 🌸
  • The editionID is OPTIONAL, and the editionIdentifier is used to distinguish accountable items. The editionID consists of either six alphanumeric characters or an integer. When present, the editionID is either a single value or a range. The integer encoding should be used when it is important to keep key package size to a minimum. πŸ“¦
  • The registerID is OPTIONAL. For electronic keying material, the registerID is usually omitted. The registerID is an accounting number assigned to identify Communications Security (COMSEC) material. The registerID is either a single value or a range. 🧾
  • The segmentID is OPTIONAL, and it distinguishes the individual symmetric keys delivered in one edition. A unique segmentNumber is assigned to each key in an edition. The segmentNumber is set to one for the first item in each edition, and it is incremented by one for each additional item within that edition. The segmentID is either a single value or a range. πŸ”’

The order the keying material shows up in the key package is a bit of a vibe, so here's an example πŸ—“οΈ A cryptographic device may need fresh keying material every day, an edition represents the keying material for a single month, and the segments represent the keying material for a day within that month. Say a key package has the keying material for July and August. That's 62 days total πŸŒ™ The keying material will appear in this order: Edition 1, Segment 1; Edition 1, Segment 2; Edition 1, Segment 3; ...; Edition 1, Segment 31; Edition 2, Segment 1; Edition 2, Segment 2; Edition 2, Segment 3; ...; Edition 2, Segment 31.

Okay, now the cross-checking drama πŸ‘€ Because of multiple layers of encapsulation or the use of content collections, the TSEC-Nomenclature attribute can appear in more than one spot in the overall key package. When there are multiple occurrences of it within the same scope, the shortTitle field MUST match in all instances. Receivers MUST reject any key package that fails these consistency checks 🚫

And one more: when the manifest attribute from Section 6 is included in an outer layer, the ShortTitle field values present in TSEC-Nomenclature attributes MUST be one of the values in the manifest attribute. Receivers MUST reject any key package that fails this consistency check. No exceptions, periodt πŸ’…


11. Key Purpose πŸ¦‹

The key-purpose attribute is all about the vibe check for the key material: what it's actually intended to be used for 🎯 It can appear as a symmetric key, symmetric key package, asymmetric key, signed, authenticated, authenticated&unprotected, or content attribute. If the key-purpose attribute appears as a signed, authenticated, authenticated&unprotected, or content attribute, then all of the keying material within the associated content MUST have the same key purpose value 🌈

The key-purpose attribute has the following syntax 🧚

  aa-keyPurpose ATTRIBUTE ::= {
    TYPE KeyPurpose
    IDENTIFIED BY id-kma-keyPurpose }

  id-kma-keyPurpose OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 13 }

  KeyPurpose ::= ENUMERATED {
    n-a    (0),   -- Not Applicable
    A     (65),   -- Operational
    B     (66),   -- Compatible Multiple Key
    L     (76),   -- Logistics Combinations
    M     (77),   -- Maintenance
    R     (82),   -- Reference
    S     (83),   -- Sample
    T     (84),   -- Training
    V     (86),   -- Developmental
    X     (88),   -- Exercise
    Z     (90),   -- "On the Air" Testing
    ... -- Expect additional key purpose values -- }

Due to multiple layers of encapsulation or the use of content collections, the key-purpose attribute can appear in more than one location in the overall key package. When there are multiple occurrences of the key-purpose attribute within the same scope, all fields within the attribute MUST contain exactly the same values. Receivers MUST reject any key package that fails these consistency checks πŸ«ΆπŸ’œ

12. Key Use πŸ”‘

Okay so the key-use attribute tells you what the key material is actually for πŸ’… It can show up as a symmetric key, symmetric key package, asymmetric, signed, authenticated, authenticated&unprotected, or content attribute. If it shows up as a signed, authenticated, authenticated&unprotected, or content attribute, then all of the keying material inside that content MUST have the same key use value. No mixing and matching, bestie 🫢

The key-use attribute has the following syntax:

  aa-key-Use ATTRIBUTE ::= {
    TYPE KeyUse
    IDENTIFIED BY id-kma-keyUse }

  id-kma-keyUse OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 14 }

  KeyUse ::= ENUMERATED {
    n-a    (0),    -- Not applicable
    ffk    (1),    -- FIREFLY/CROSSTALK Key (Basic Format)
    kek    (2),    -- Key Encryption Key
    kpk    (3),    -- Key Production Key
    msk    (4),    -- Message Signature Key
    qkek   (5),    -- QUADRANT Key Encryption Key
    tek    (6),    -- Traffic Encryption Key
    tsk    (7),    -- Transmission Security Key
    trkek  (8),    -- Transfer Key Encryption Key
    nfk    (9),    -- Netted FIREFLY Key
    effk  (10),    -- FIREFLY Key (Enhanced Format)
    ebfk  (11),    -- FIREFLY Key (Enhanceable Basic Format)
    aek   (12),    -- Algorithm Encryption Key
    wod   (13),    -- Word of Day
    kesk (246),    -- Key Establishment Key
    eik  (247),    -- Entity Identification Key
    ask  (248),    -- Authority Signature Key
    kmk  (249),    -- Key Modifier Key
    rsk  (250),    -- Revocation Signature Key
    csk  (251),    -- Certificate Signature Key
    sak  (252),    -- Symmetric Authentication Key
    rgk  (253),    -- Random Generation Key
    cek  (254),    -- Certificate Encryption Key
    exk  (255),    -- Exclusion Key
    ... -- Expect additional key use values -- }

Here's the vibe for each value 🌈

  • ffk: A FIREFLY/CROSSTALK key is used to establish a Key Establishment Key (KEK) or a Transmission Encryption Key (TEK) between two parties. The KEK or TEK generated from the exchange is used with a symmetric encryption algorithm. This key use value is associated with keys in the basic format.
  • kek: A Key Encryption Key is used to encrypt or decrypt other keys for transmission or storage.
  • kpk: A Key Production Key is used to initialize a keystream generator for the production of other electronically generated keys.
  • msk: A Message Signature Key is used in a digital signature process that operates on a message to assure message source authentication, message integrity, and non-repudiation.
  • qkek: QUADRANT Key Encryption Key is one part of a tamper-resistance solution.
  • tek: A Traffic Encryption Key is used to encrypt plaintext, to superencrypt previously encrypted data, and/or to decrypt ciphertext.
  • tsk: A Transmission Security Key is used to protect transmissions from interception and exploitation by means other than cryptanalysis.
  • trkek: Transfer Key Encryption Key. The keys used to protect communications with an intermediary.
  • nfk: A Netted FIREFLY Key is a FIREFLY key that has an edition number associated with it. When rekeyed, it is incremented, preventing communications with FIREFLY key of previous editions. This edition number is maintained within a universal edition.
  • effk: Enhanced FIREFLY Key is used to establish a KEK or a TEK between two parties. The KEK or TEK generated from an exchange is used with a symmetric encryption algorithm. This key use value is associated with keys in the enhanced format.
  • ebfk: Enhanceable Basic FIREFLY Key is used to establish a KEK or a TEK between two parties. The KEK or TEK generated from an exchange is used with a symmetric encryption algorithm. This key use value is associated with keys in the enhanceable basic format.
  • aek: An Algorithm Encryption Key is used to encrypt or decrypt an algorithm implementation as well as other functionality in the implementation.
  • wod: A key used to generate the Word of the Day (WOD).
  • kesk: A Key Establishment Key is an asymmetric key set (e.g., public/private/parameters) used to enable the establishment of symmetric key(s) between entities.
  • eik: An Entity Identification Key is an asymmetric key set (e.g., public/private/parameters) used to identify one entity to another for access control and other similar purposes.
  • ask: An Authority Signature Key is an asymmetric key set (e.g., public/private/parameters) used by designated authorities to sign objects such as Trust Anchor Management Protocol (TAMP) messages and firmware packages.
  • kmk: A Key Modifier Key is a symmetric key used to modify the results of the process that forms a symmetric key from a public key exchange process.
  • rsk: A Revocation Signature Key is an asymmetric key set (e.g., public/private/parameters) used to sign and authenticate revocation lists and compromised key lists.
  • csk: A Certificate Signature Key is an asymmetric key set (e.g., public/private/parameters) used to sign and authenticate public key certificates.
  • sak: A Symmetric Authentication Key is used in a MAC algorithm to provide message integrity. Differs from a Message Signature Key in that it is symmetric key material and it does not provide source authentication or non-repudiation.
  • rgk: Random Generation Key is a key used to seed a deterministic pseudorandom number generator.
  • cek: A Certificate Encryption Key is used to encrypt public key certificates to support privacy.
  • exk: An Exclusion Key is a symmetric key used to cryptographically subdivide a single large security domain into smaller segregated domains.

Because of multiple layers of encapsulation or the use of content collections, the key-use attribute can show up in more than one spot in the overall key package πŸŽ€ When there are multiple occurrences of the key-use attribute within the same scope, all fields within the attribute MUST contain exactly the same values. Receivers MUST reject any key package that fails these consistency checks. Not a vibe, a rule πŸ’€


13. Transport Key πŸ¦‹

So the transport-key attribute tells you whether an asymmetric key is a transport key or an operational key, which is basically whether or not the key can be used as is πŸ“ It can appear as an asymmetric key, signed, authenticated, authenticated&unprotected, or content attribute. If it appears as a signed, authenticated, authenticated&unprotected, or content attribute, then all of the keying material inside that content MUST have the same operational/transport key material. Same energy as before, no drama ✨

  aa-transportKey ATTRIBUTE ::= {
    TYPE TransOp
    IDENTIFIED BY id-kma-transportKey }

  id-kma-transportKey OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 15 }

  TransOp ::= ENUMERATED {
    transport    (1),
    operational  (2) }

Due to multiple layers of encapsulation or the use of content collections, the transport-key attribute can appear in more than one location in the overall key package 🧚 When there are multiple occurrences of the transport-key attribute within the same scope, all fields within the attribute MUST contain exactly the same values. Receivers MUST reject any key package that fails these consistency checks. Iykyk, and now you do 🫢


14. Key Distribution Period 🌸

Okay this one is so pretty. The key-distribution-period attribute tells you the window of time the keying material is meant to be distributed in πŸ•°οΈ Keying material often gets distributed before it's actually meant to be used, so the timing matters. Time of day must be represented in Coordinated Universal Time (UTC). It can appear as a symmetric key, symmetric key package, asymmetric key, signed, authenticated, authenticated&unprotected, or content attribute. If it appears as a signed, authenticated, authenticated&unprotected, or content attribute, then all of the keying material within the content MUST have the same key distribution period. Main character energy for the timestamps πŸ‘‘

The key-distribution-period attribute has the following syntax:

  aa-keyDistributionPeriod ATTRIBUTE ::= {
    TYPE KeyDistPeriod
    IDENTIFIED BY id-kma-keyDistPeriod }

  id-kma-keyDistPeriod OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 5 }

  KeyDistPeriod ::= SEQUENCE {
    doNotDistBefore  [0] BinaryTime OPTIONAL,
    doNotDistAfter       BinaryTime }

  BinaryTime ::= INTEGER

The fields in the key-distribution-period attribute have these semantics:

  • doNotDistBefore is OPTIONAL. When it's present, the keying material SHOULD NOT be distributed before the date and time it gives πŸ™ˆ
  • doNotDistAfter is REQUIRED, and the keying material SHOULD NOT be distributed after the date and time it gives πŸ’–

When the key-distribution-period attribute is attached to a collection of keying material, the distribution period applies to every key in that collection. None of the keying material in the collection SHOULD be distributed outside the indicated period πŸ¦‹

Because of multiple layers of encapsulation or the use of content collections, the key-distribution-period attribute can show up in more than one spot in the overall key package 🌈 When there are multiple occurrences of the key-distribution-period attribute within the same scope, all of the included attribute fields MUST contain exactly the same value. However, if the doNotDistBefore field is absent in an inner layer, a value MAY appear in an outer layer, because the outer layer constrains the inner layer. Receivers MUST reject any key package that fails these consistency checks. Consistency is everything, periodt πŸ’…

15. Key Validity Period ✨

okay bestie, this section is all about the key-validity-period attribute πŸ—“οΈπŸ’– it tells you the window of time the keying material is actually meant to be used. and the time of day? it MUST be written in Coordinated Universal Time (UTC) 🌍 no time zone drama allowed πŸ’…

the attribute can show up as a symmetric key, symmetric key package, asymmetric key, signed, authenticated, authenticated&unprotected, or content attribute πŸŽ€ and if it lives in a signed, authenticated, authenticated&unprotected, or content attribute, then ALL the keying material inside that content MUST have the same key validity period. no mixing and matching, periodt πŸ™…β€β™€οΈβœ¨

15.1. Syntax ✨

here's the vibe of the syntax 🧚

  aa-keyValidityPeriod ATTRIBUTE ::= {
    TYPE KeyValidityPeriod
    IDENTIFIED BY id-kma-keyValidityPeriod }

  id-kma-keyValidityPeriod OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 6 }

  KeyValidityPeriod ::= SEQUENCE {
    doNotUseBefore      BinaryTime,
    doNotUseAfter       BinaryTime OPTIONAL }

  BinaryTime ::= INTEGER

15.2. Semantics ✨

so the fields work like this 🫢

  • the doNotUseBefore field is REQUIRED πŸ’œ and the keying material SHOULD NOT be used before that date and time
  • the doNotUseAfter field is OPTIONAL 🌸 but if it's there, the keying material SHOULD NOT be used after that date and time

lowkey a fun detail: for a key package used for rekey, some templates might REQUIRE doNotUseAfter even though the syntax says OPTIONAL πŸ™ˆ so check your templates, bestie πŸ”

when this attribute is tied to a whole collection of keying material, the validity period covers EVERY key in the collection 🧺✨ none of them SHOULD be used outside that window πŸ’€

15.3. Relationship to Key Duration ✨

okay so key-validity-period and key-duration (the next section πŸ¦‹) are like two halves of the same vibe πŸ’… validity period gives you explicit start and end times for when the keying material can be used πŸ—“οΈ while key-duration gives the maximum length of time it SHOULD be used ⏳

if both show up, the duration MAY happen at any point inside the validity period 🌈 but the limits from BOTH attributes SHOULD be honored 🫢 literally both, no picking favourites πŸ‘‘

15.4. Multiple Occurrences ✨

sometimes this attribute appears in more than one spot in the key package because of layers of encapsulation or content collections 🎁 when that happens in the same scope, ALL the included attribute fields MUST contain exactly the same value πŸ™…β€β™€οΈ

one twist: if doNotUseAfter is missing from an inner layer, an outer layer MAY supply a value πŸ§… and receivers MUST reject any key package that fails these consistency checks πŸ’€πŸš« no exceptions, iykyk 😭


16. Key Duration ✨

the key-duration attribute tells you the maximum amount of time the keying material is meant to be used πŸ•°οΈ it doesn't say WHEN the clock starts πŸ€·β€β™€οΈ it just caps how long the keying material can provide security services πŸ›‘οΈ so main character energy for the duration ✨

like the validity period, it can appear as a symmetric key, symmetric key package, asymmetric key, signed, authenticated, authenticated&unprotected, or content attribute πŸŽ€ and if it's a signed, authenticated, authenticated&unprotected, or content attribute, then ALL the keying material inside MUST have the same key duration πŸ’…

16.1. Syntax ✨

  aa-keyDurationPeriod ATTRIBUTE ::= {
    TYPE KeyDuration
    IDENTIFIED BY id-kma-keyDuration }

  id-kma-keyDuration OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 7 }

  KeyDuration ::= CHOICE {
    hours      [0] INTEGER (1..ub-KeyDuration-hours),
    days           INTEGER (1..ub-KeyDuration-days),
    weeks      [1] INTEGER (1..ub-KeyDuration-weeks),
    months     [2] INTEGER (1..ub-KeyDuration-months),
    years      [3] INTEGER (1..ub-KeyDuration-years) }

  ub-KeyDuration-hours  INTEGER ::=  96
  ub-KeyDuration-days   INTEGER ::= 732
  ub-KeyDuration-weeks  INTEGER ::= 104
  ub-KeyDuration-months INTEGER ::=  72
  ub-KeyDuration-years  INTEGER ::= 100

16.2. Relationship to Key Validity Period ✨

the key-duration and key-validity-period attributes are complementary, so they team up 🀝 the relationship between them is explained back in the previous section πŸ¦‹

16.3. Multiple Occurrences ✨

same deal as before πŸŽ€ the key-duration attribute can show up in more than one location because of layers of encapsulation or content collections πŸ§… when there are multiple occurrences in the same scope, ALL the included attribute fields MUST contain exactly the same value πŸ’– and receivers MUST reject any key package that fails these consistency checks πŸš«πŸ’€


17. Classification πŸ”

the classification attribute tells you the level of classification πŸ•΅οΈβ€β™€οΈ specifically, it's the aggregate classification of the whole package content πŸ“¦ it can appear as a symmetric key, symmetric key package, asymmetric key, signed, authenticated, authenticated&unprotected, or content attribute πŸŽ€

if the classification attribute is a signed, authenticated, authenticated&unprotected, or content attribute, then its value MUST represent the classification of ALL the keying material in the content πŸ’… encrypted layers MAY hold content at a higher classification that only gets revealed once they're decrypted 🫣 and if the attribute is tied to a collection, the sensitivity of all the data in that collection MUST be dominated by the classification in this attribute πŸ‘‘

this attribute makes use of the ESSSecurityLabel from Section 17.1 🏷️ plus [RFC2634] and [RFC5911] πŸ“š the document calls it "classification," but [RFC2634] calls it "security label" πŸ™ƒ same exact meaning, no cap 🧒

17.1. Syntax ✨

[RFC2634] and [RFC5911] already define an object identifier and syntax for the security label attribute, and the classification attribute uses the SAME values 🀝

  aa-classificationAttribute ATTRIBUTE ::= {
    TYPE Classification
    IDENTIFIED BY id-aa-KP-classification }

  id-aa-KP-classification OBJECT IDENTIFIER ::= id-aa-securityLabel

  -- id-aa-securityLabel OBJECT IDENTIFIER ::= {
  --  iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
  --   pkcs-9(9) smime(16) id-aa(2) 2 }

  Classification ::= ESSSecurityLabel

the ESSSecurityLabel syntax isn't repeated here πŸ“ but you MUST follow the security label conventions in Section 17.1 when implementing this spec 🫢 for the full semantics and syntax, go read [RFC2634] πŸ“–

17.2. Multiple Occurrences ✨

when the classification attribute shows up in more than one spot in the key package, each occurrence is evaluated on its own πŸ” the content originator MUST make sure the classification represents the sensitivity of the plaintext within the content 🫢 so it MUST dominate any other plaintext classification attribute value elsewhere in the key package πŸ‘‘

tea moment β˜• the classification value MAY go higher than those other plaintext values, but only if the other values in the SignerInfo, AuthEnvelopedData, or AuthenticatedData are themselves classified and deserve the higher label πŸ”

17.3. Security Policies ✨

if the classification attribute appears in multiple places, each security label might belong to a different security policy 🌈 content originators SHOULD avoid mixing multiple security policies in the same key package whenever possible πŸ™…β€β™€οΈ because receivers and intermediaries that check classification values then need support for the union of ALL those policies πŸ˜΅β€πŸ’«

failing to recognize an included security policy MUST result in rejection of the key package πŸ’€πŸš«

17.4. Receiver Authorization ✨

receivers MUST reject any key package that includes a classification their processing environment is NOT authorized for πŸ›‘βœ¨ no peeking at stuff you aren't cleared for, bestie πŸ•ΆοΈ

17.1. Security Label ✨

okay so the ESSSecurityLabel ASN.1 type is what we use to represent the classification πŸŽ€ it's defined in Section 3.2 of [RFC2634], and I'm copying the syntax here so we can vibe over it together πŸ’…

ESSSecurityLabel ::= SET {
  security-policy-identifier SecurityPolicyIdentifier,
  security-classification    SecurityClassification OPTIONAL,
  privacy-mark               ESSPrivacyMark OPTIONAL,
  security-categories        SecurityCategories OPTIONAL }

ESSPrivacyMark ::= CHOICE {
  pString      PrintableString (SIZE (1..ub-privacy-mark-length)),
  utf8String   UTF8String (SIZE (1..MAX)) }

so a security policy is basically a set of criteria for providing security services πŸ”₯ the security-policy-identifier is an object identifier, and it's how you figure out which policy the label belongs to. it tells you what the other label components actually mean 🧚

if the key package receiver doesn't recognize the object identifier in security-policy-identifier AND the label includes a security-categories field, then the key package contents MUST NOT be accepted and the enclosed keying material MUST NOT be used πŸ™ˆ no exceptions, bestie.

if the receiver doesn't recognize the OID and the label does NOT include security-categories, the key package contents MAY be accepted, but only if security-classification is present and holds a value from the basic hierarchy (more on that below) 🌸

this spec uses the SecurityClassification field exactly as it's specified in the 1988 edition of ITU-T Recommendation X.411 [X.411] πŸ’– and X.411 says, in part:

If present, a security-classification may have one of a hierarchical list of values. The basic security-classification hierarchy is defined in this Recommendation, but the use of these values is defined by the security-policy in force. Additional values of security-classification, and their position in the hierarchy, may also be defined by a security-policy as a local matter or by bilateral agreement. The basic security-classification hierarchy is, in ascending order: unmarked, unclassified, restricted, confidential, secret, top-secret.

implementations MUST support the basic security classification hierarchy ✨ they MAY also support other security-classification values, but the placement of any additional values in the hierarchy MUST be specified by the security policy πŸ¦‹

implementations MUST NOT make access control decisions based on the privacy-mark πŸ™… BUT the info in it can be shown to human users by devices with displays, so it's not totally invisible lol. the privacy-mark length MUST NOT exceed 128 characters πŸ“ and the privacy-mark SHALL use the PrintableString choice if all of its characters are members of the printable string character set 🫢

if security-categories is present, it gives extra granularity for the keying material πŸ”₯ the security policy in force says which syntaxes are permitted for entries in the set of security categories, and at most 64 security categories may be present πŸ‘‘ the SecurityCategories and SecurityCategory types come from [RFC5912], and here they are again so we can stare at them together:

SecurityCategories ::= SET SIZE (1..ub-security-categories) OF
                         SecurityCategory
                           {{SupportedSecurityCategories}}

SecurityCategory {SECURITY-CATEGORY:Supported} ::= SEQUENCE {
    type      [0]  IMPLICIT SECURITY-CATEGORY.
                     &id({Supported}),
    value     [1]  EXPLICIT SECURITY-CATEGORY.
                     &Type({Supported}{@type})
}

there are four security categories: the Restrictive Tag, the Enumerated Tag, the Permissive Tag, and the Informative Tag πŸ’œ only the Enumerated Tag and the Informative Tag are permitted in the classification attribute, so the other two are a no-go there πŸ™…β€β™€οΈ

the Enumerated Tag is one or more non-negative integers 🌈 each integer stands for a non-hierarchical security attribute that applies to the labeled content. a security policy might define a huge set of category attributes, but a particular key package usually only carries a few, so using integers keeps the label small 🧚 these attributes could be restrictive (like compartments) or permissive (like release permissions) πŸŽ€ there are two OIDs for the SecurityCategory type field, one for restrictive and one for permissive:

id-enumeratedRestrictiveAttributes OBJECT IDENTIFIER ::= {
  2 16 840 1 101 2 1 8 3 4 }

id-enumeratedPermissiveAttributes OBJECT IDENTIFIER ::= {
  2 16 840 1 101 2 1 8 3 1 }

for both the restrictive and permissive category types, the SecurityCategory value looks like this:

EnumeratedTag ::= SEQUENCE {
  tagName          OBJECT IDENTIFIER,
  attributeList    SET OF SecurityAttribute }

SecurityAttribute ::= INTEGER (0..MAX)

any security policy that uses security categories MUST assign object identifiers for each tagName, assign the set of integer values for each tagName, and specify the semantic meaning of each integer value πŸ’… and restrictive and permissive security attributes SHOULD be tied to different tagName OIDs πŸ¦‹

the Informative Tag is either a) one or more non-negative integers or b) a bit string 🌸 but only the integer choice is allowed in this spec. each integer is again a non-hierarchical security attribute, and integers keep the label small for the same reason as before πŸ“ attributes under this tag are informative, meaning no access control is performed πŸ‘€ there's one OID for it:

id-informativeAttributes OBJECT IDENTIFIER ::= {
  2 16 840 1 101 2 1 8 3 3 }

and the SecurityCategory value looks like this:

InformativeTag ::= SEQUENCE {
  tagName     OBJECT IDENTIFIER,
  attributes  FreeFormField }

FreeFormField ::= CHOICE {
  bitSetAttributes    BIT STRING,
  securityAttributes  SET OF SecurityAttribute }

same deal: any security policy using security categories MUST assign object identifiers for each tagName, assign the set of integer values for each tagName, and specify the semantic meaning of each integer value 🫢


18. Split Identifier ✨

so the key package originator can include a split-identifier attribute to say the keying material is a split key and not a complete one πŸ”‘ it can show up as a symmetric or asymmetric key attribute πŸ¦‹ but the split-identifier attribute MUST NOT appear as a symmetric key package, signed, authenticated, authenticated&unprotected, or content attribute πŸ™ˆ

split keys have two halves, called "A" and "B" πŸ’œ the split-identifier attribute says which half is in the package, and it can optionally say which algorithm combines the two halves 🧚 the combine algorithm is OPTIONAL, since every key algorithm already has a default mechanism for this, and the combine algorithm is only there when that default isn't used 🌸

the syntax is:

aa-splitIdentifier ATTRIBUTE ::= {
  TYPE SplitID
  IDENTIFIED BY id-kma-splitID }

id-kma-splitID OBJECT IDENTIFIER ::= {
  joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
  dod(2) infosec(1) keying-material-attributes(13) 11 }

SplitID ::= SEQUENCE {
  ENUMERATED { a(0), b(1) },
  combineAlg  AlgorithmIdentifier
              {COMBINE-ALGORITHM, {CombineAlgorithms}} OPTIONAL }

in most cases the default combine algorithm gets used, which makes this attribute a simple constant that just names the "A" or "B" half πŸ“ that helps with some key distribution policies πŸ’–

each split might have its own CRC, but the key and the check word both come back when the two splits are combined πŸŽ€

since the split-identifier attribute MUST NOT appear as a signed, authenticated, authenticated&unprotected, or content attribute, a key package can't have multiple occurrences of the split-identifier attribute in the same scope πŸ™…β€β™€οΈ and receivers MUST reject any key package where the split-identifier attribute shows up as a signed, authenticated, authenticated&unprotected, or content attribute 😭


19. Key Package Type ✨

the key-package-type attribute is a shorthand for specifying every aspect of the key package format πŸ‘‘ that includes which attributes are present and how the encapsulated content or collection is structured 🌈 it can be used as a signed, authenticated, authenticated&unprotected, or content attribute πŸ’…

rather than implementing the full flexibility of this spec, some devices may only support one or more specific key package formats that instantiate it 🧚 those specific formats are called templates, and you can identify them with a key-package-type attribute ✨

the syntax is:

aa-keyPackageType ATTRIBUTE ::= {
  TYPE KeyPkgType
  IDENTIFIED BY id-kma-keyPkgType }

id-kma-keyPkgType OBJECT IDENTIFIER ::= {
  joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
  dod(2) infosec(1) keying-material-attributes(13) 12 }

KeyPkgType ::= OBJECT IDENTIFIER

because of multiple layers of encapsulation or the use of content collections, the key-package-type attribute can show up in more than one spot in the overall key package 🫢 when that happens, each occurrence is used independently πŸ¦‹ and since the receiver will probably use the key-package-type value as a decoding aid, any error will most likely cause parsing problems, and those problems could get reported as lots of different errors πŸ’€

20. Signature Usage πŸ’…

Okay bestie, the signature-usage attribute tells you which CMS content types this key can sign, or which content types the end-entity key in a cert path validated by this key is allowed to sign πŸ–ŠοΈ. Symmetric key packages have no signature generation or validation keying material at all, so the signature-usage attribute MUST NOT appear in a symmetric key package πŸ™…β€β™€οΈ. For an asymmetric key package, it shows what kind of objects get signed with the private key inside the package. But if the package has a Certificate Signature Key, it also tells you what signed objects can be validated with certificates signed by that private key, which means it also says what kinds of objects can be signed by the private keys tied to those certificates 🧠✨ The signature-usage attribute MUST NOT appear as a signed, authenticated, authenticated&unprotected, or content attribute 🚫.

The attribute looks like this:

  aa-signatureUsage-v3 ATTRIBUTE ::= {
    TYPE SignatureUsage
    IDENTIFIED BY id-kma-sigUsageV3 }

  id-kma-sigUsageV3 OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 22 }

  SignatureUsage ::= CMSContentConstraints

The SignatureUsage structure has the same syntax as the CMSContentConstraints structure from [RFC6010], and it's repeated here for convenience πŸŽ€

  CMSContentConstraints ::= SEQUENCE SIZE (1..MAX) OF
                             ContentTypeConstraint

  ContentTypeGeneration ::= ENUMERATED  {
    canSource(0),
    cannotSource(1)}

  ContentTypeConstraint ::= SEQUENCE {
    contentType      CONTENT-TYPE.&id ({ContentSet|ct-Any,...}),
    canSource        ContentTypeGeneration DEFAULT canSource,
    attrConstraints  AttrConstraintList OPTIONAL }

  Constraint { ATTRIBUTE:ConstraintList } ::= SEQUENCE {
    attrType    ATTRIBUTE.&id({ConstraintList}),
    attrValues  SET SIZE (1..MAX) OF ATTRIBUTE.
                  &Type({ConstraintList}{@attrType})  }

  SupportedConstraints ATTRIBUTE ::= {SignedAttributesSet, ... }

  AttrConstraintList ::= SEQUENCE SIZE (1..MAX) OF
                         Constraint {{ SupportedConstraints }}

  NOTE: SignedAttributesSet is updated by this specification.

A SignatureUsage is a CMSContentConstraints. One or more ContentTypeConstraint MUST appear in CMSContentConstraints πŸ“‹

Inside a ContentTypeConstraint, the contentType field names the encapsulated content type identifier that can be signed with the signature key. A particular content type MUST NOT appear more than once in the list πŸ™…β€β™€οΈ The CMS protecting content types don't need to be in the list of permitted content types, because CMS is always authorized (see [RFC6010]) πŸ”

The canSource enumeration says whether the signature key can directly sign the indicated content type. If the ContentTypeConstraint is canSource (the default value), the signature key can directly sign that content type πŸ–‹οΈ If it's cannotSource, the signature key can only be used with that content type when it encapsulates a signature generated by an originator whose ContentTypeConstraint is canSource 🌸

Within ContentTypeList, the attrConstraints OPTIONAL field holds a sequence of constraints specific to the content type. If attrConstraints is absent, the signature key can sign that content type with no further checking βœ… If attrConstraints is present, the signature key can only sign that content type if every constraint for it is satisfied πŸ’… Constraints get checked by matching the attribute values in attrConstraint against the attribute values in the content. The constraints succeed if the attribute isn't present, and they fail if the attribute is present but its value isn't one of the values provided in attrConstraint πŸ‘€

The fields of attrConstraints implement constraints specific to each content type. The attrType field is an AttributeType, an object identifier of a signed attribute carried in the SignerInfo of the content. The attrValues field gives one or more acceptable signed attribute values; it's a set of AttributeValue. For signed content to satisfy the constraint, the SignerInfo MUST include a signed attribute of the type identified in attrType, and that signed attribute MUST contain one of the values in the set carried in attrValues πŸ¦‹

Since the signature-usage attribute MUST NOT appear as a signed, authenticated, authenticated&unprotected, or content attribute, an asymmetric key package can't include multiple occurrences of the signature-usage attribute within the same scope πŸ™ƒ Receivers MUST reject any asymmetric key package in which the signature-usage attribute appears as a signed, authenticated, authenticated&unprotected, or content attribute πŸ›‘


21. Other Certificate Format 🌈

The other-certificate-formats attribute specifies the type, format, and value of certificates that aren't X.509 public key certificates πŸ“œ Symmetric key packages don't contain any certificates, so the other-certificate-formats attribute MUST NOT appear in a symmetric key package πŸ™…β€β™€οΈ It SHOULD appear in the attributes field when the publicKey field is absent and the certificate format isn't X.509 🫢 This attribute MUST NOT appear in an attributes field that includes the user-certificate attribute from Section 8. And it MUST NOT appear as a signed, authenticated, authenticated&unprotected, or content attribute 🚫

Here's the syntax:

  aa-otherCertificateFormats ATTRIBUTE ::= {
    TYPE CertificateChoices
    IDENTIFIED BY id-kma-otherCertFormats }

  id-kma-otherCertFormats OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 19 }

  CertificateChoices ::= CHOICE {
    certificate             Certificate,
    extendedCertificate [0] IMPLICIT ExtendedCertificate,
                                     -- Obsolete
    v1AttrCert          [1] IMPLICIT AttributeCertificateV1,
                                     -- Obsolete
    v2AttrCert          [2] IMPLICIT AttributeCertificateV2,
    other               [3] IMPLICIT OtherCertificateFormat }

  OtherCertificateFormat ::= SEQUENCE {
    otherCertFormat           OBJECT IDENTIFIER,
    otherCert ANY DEFINED BY  otherCertFormat }

This attribute uses the CertificateChoices field defined in Section 10.2.2 of [RFC5652] 🧩 The certificate, extendedCertificate, and v1AttrCert fields MUST be omitted πŸ™ˆ The v2AttrCert field can hold Version 2 Attribute Certificates. The other field can hold Enhanced FIREFLY certificates and other certificate formats that haven't been defined yet ✨

Since the other-certificate-formats attribute MUST NOT appear as a signed, authenticated, authenticated&unprotected, or content attribute, an asymmetric key package can't include multiple occurrences of it within the same scope πŸ™ƒ Receivers MUST reject any asymmetric key package in which the other-certificate-formats attribute appears as a signed, authenticated, authenticated&unprotected, or content attribute πŸ›‘


22. PKI Path πŸ›€οΈ

The pki-path attribute includes certificates that can help validate the certificate carried in the user-certificate attribute πŸ—οΈ Symmetric key packages don't contain any certificates, so the pkiPath attribute MUST NOT appear in a symmetric key package πŸ™…β€β™€οΈ It can appear as an asymmetric key, signed, authenticated, authenticated&unprotected, or content attribute. It can also appear in the attributes field when the publicKey field is absent and the certificate format is X.509 πŸ’– This attribute MUST NOT appear in an AsymmetricKeyPackage that has an other-certificate-formats attribute in its attributes field 🚫 If pki-path appears as a signed, authenticated, authenticated&unprotected, or content attribute, its value includes certificates that can build a certification path to all of the keying material in the content 🧭 This attribute MUST be supported πŸ’―

The syntax comes from [X.509], but it's redefined using the ATTRIBUTE CLASS from [RFC5912]:

  aa-pkiPath ATTRIBUTE ::= {
    TYPE PkiPath
    IDENTIFIED BY id-at-pkiPath }

  id-at-pkiPath OBJECT IDENTIFIER ::= {
   joint-iso-itu-t(2) ds(5) attributes(4) 70 }

  PkiPath ::= SEQUENCE SIZE (1..MAX) OF Certificate

The first certificate in the sequence is the subject's parent Certification Authority (CA). The next certificate is that CA's parent, and so on 🌳 The end-entity and trust anchor are NOT included in this attribute πŸ™…β€β™€οΈ

Because of multiple layers of encapsulation or the use of content collections, the pki-path attribute can appear in more than one location in the overall key package. When that happens, each occurrence is evaluated independently πŸ”


23. Useful Certificates 🎁

The useful-certificates attribute includes certificates that can help validate certificates belonging to other parties you're expecting to have secure communications with 🀝 It can appear as an asymmetric key, signed, authenticated, authenticated&unprotected, or content attribute. For an asymmetric key that has an other-certificate-formats attribute (Section 21) in its attributes field, the useful-certificates attribute MUST NOT appear πŸ™…β€β™€οΈ If useful-certificates appears as a signed, authenticated, authenticated&unprotected, or content attribute, its value includes certificates that may be used to validate certificates of others the receiver communicates with πŸ’œ This attribute MUST be supported πŸ’―

Here's the syntax:

  aa-usefulCertificates ATTRIBUTE ::= {
    TYPE CertificateSet
    IDENTIFIED BY id-kma-usefulCerts }

  id-kma-usefulCerts OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
    dod(2) infosec(1) keying-material-attributes(13) 20 }

  CertificateSet ::= SET OF CertificateChoices

The useful-certificates attribute uses the CertificateSet field defined in Section 10.2.3 of [RFC5652]. Within the CertificateChoices field, the extendedCertificate and v1AttrCert fields MUST always be omitted πŸ™ˆ If the userCertificate attribute from Section 8 is included, the other field MUST NOT be present. And if the other-certificate-formats attribute (Section 21) is included, the certificate field MUST NOT be present 🧩

Because of multiple layers of encapsulation or the use of content collections, the useful-certificates attribute can appear in more than one location in the overall key package. When it appears in more than one location, each occurrence is evaluated independently πŸ”

24. Key Wrap Algorithm ✨

okay so the key-wrap-algorithm attribute tells you which key wrap algorithm got used, using an algorithm identifier πŸ” it can show up as a symmetric key attribute or a symmetric key package attribute. when it's in sKeyAttrs, the sKey field holds a black key (basically an encrypted key) that was wrapped by that algorithm. when it's in sKeyPkgAttrs, every sKey in that package is a black key, and they've ALL been wrapped by the same designated algorithm. no mixing, periodt πŸ’…

the syntax is giving very formal, but here it is:

aa-keyWrapAlgorithm ATTRIBUTE ::= {
  TYPE AlgorithmIdentifier{KEY-WRAP, {KeyEncryptionAlgorithmSet}}
  IDENTIFIED BY id-kma-keyWrapAlgorithm }

id-kma-keyWrapAlgorithm OBJECT IDENTIFIER ::= {
  joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
  dod(2) infosec(1) keying-material-attributes(13) 21 }

KeyEncryptionAlgorithmSet KEY-WRAP ::= { ... }

25. Content Decryption Key Identifier πŸ¦‹

the content-decryption-key-identifier attribute can show up as an unprotected attribute AND as a symmetric or symmetric key package attribute. and the meaning changes depending on where it lives, so pay attention bestie πŸ‘€

25.1. Content Decryption Key Identifier: Symmetric Key and Symmetric Key Package 🌸

the content-decryption-key-identifier attribute [RFC6032] tells you which keying material you need to decrypt the sKey. it can be a symmetric key attribute or a symmetric key package attribute. if key-wrap-algorithm is in sKeyPkgAttrs, then the matching content-decryption-identifier can be in either sKeyPkgAttrs or sKeyAttrs. but if key-wrap-algorithm (Section 24) is in sKeyAttrs, then the matching content-decryption-identifier MUST be in sKeyAttrs too. no skipping that one πŸ™…β€β™€οΈ

this attribute is included for convenience, and here's how it's defined:

aa-contentDecryptKeyIdentifier ATTRIBUTE ::= {
  TYPE ContentDecryptKeyID
  IDENTIFIED BY id-aa-KP-contentDecryptKeyID }

id-aa-KP-contentDecryptKeyID OBJECT IDENTIFIER ::= {
  joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
  dod(2) infosec(1) attributes(5) 66 }

ContentDecryptKeyID ::= OCTET STRING

the content decryption key identifier is an octet string, and the syntax doesn't force any particular structure on the value. it's giving freedom 🧚

25.2. Content Decryption Key Identifier: Unprotected πŸŽ€

the content-decryption-key-identifier attribute can be used to identify the keying material needed to decrypt the EncryptedData content when things are ambiguous. so basically, when it's unclear which key to use, this is your tiebreaker ✨

the syntax lives in Section 25.1, so go check there. same deal: it's an octet string with no required structure πŸ’œ

now the important bit. because there are multiple layers of encryption, this attribute can show up in more than one spot in the whole key package. when that happens, each occurrence gets evaluated on its own, and each one identifies the keying material for its own layer of encryption. one attribute per layer, no mixing them up 🫢


26. Certificate Pointers πŸ“

the certificate-pointers attribute can point to one or more certificates that might help with processing the content once it's decrypted. sometimes certs get left out because they can be easily fetched, but an intermediary might be better at fetching than the receiver is, so the pointers are useful πŸ’– this attribute can show up as an unprotected attribute and as an unauthenticated&unprotected attribute.

the certificate-pointers attribute uses the exact same syntax and semantics as the subject information access certificate extension [RFC5280], so it's basically a copy of that πŸͺž here's the syntax:

aa-certificatePointers ATTRIBUTE ::= {
  TYPE SubjectInfoAccessSyntax
  IDENTIFIED BY id-pe-subjectInfoAccess }

id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= {
  iso(1) identified-organization(3) dod(6) internet(1)
  security(5) mechanisms(5) pkix(7) pe(1) 11 }

SubjectInfoAccessSyntax ::= SEQUENCE SIZE (1..MAX) OF
                              AccessDescription

AccessDescription ::= SEQUENCE {
  accessMethod       OBJECT IDENTIFIER,
  accessLocation     GeneralName }

as [RFC5280] says, the id-ad-caRepository access method can point to a repository where a Certification Authority publishes certificates and Certificate Revocation Lists (CRLs). in that case, the accessLocation field tells you how to reach the repository. if the info is reachable over HTTP, FTP, or the Lightweight Directory Access Protocol (LDAP), accessLocation holds a Uniform Resource Identifier (URI). if it's reachable over the Directory Access Protocol (DAP), accessLocation holds a directory name πŸ—ΊοΈ


27. CRL Pointers 🌈

the CRL-pointers attribute can reference one or more CRLs that might help with processing the content once it's decrypted. CRLs sometimes get left out to save space, or so you can make sure you grab the most recent one when you validate the certificate ⏰ again, an intermediary might be better at fetching them than the receiver, so this attribute can be useful in some environments. it can show up as an unprotected attribute and as an unauthenticated&unprotected attribute.

the CRL-pointers attribute has this syntax:

aa-crlPointers ATTRIBUTE ::= {
  TYPE GeneralNames
  IDENTIFIED BY id-aa-KP-crlPointers }

id-aa-KP-crlPointers OBJECT IDENTIFIER ::= {
  joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
  dod(2) infosec(1) attributes(5) 70 }

it uses the GeneralNames syntax from [RFC5280]. every name describes a different way to get the same CRL, so you get multiple routes to one destination πŸš— if the info is available over HTTP, FTP, or LDAP, GeneralNames holds a URI. if it's available over DAP, GeneralNames holds a directory name.


28. Key Package Identifier and Receipt Request πŸ’…

the key-package-identifier-and-receipt-request attribute from [RFC7191] is also supported ✨ it can show up as a signed attribute, an authenticated attribute, an authenticated&unprotected attribute, or a content attribute. it's a whole vibe with a lot of options 🫧


29. Additional Error Codes πŸ™ˆ

this spec also defines three extra extended ErrorCodeChoice object identifiers for the oid field [RFC7191]. okay wait, it's actually four, so let's just list them all 😭

id-errorCodes OBJECT IDENTIFIER ::= {
  joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
  dod(2) infosec(1) errorCodes(22) }

id-missingKeyType OBJECT IDENTIFIER ::= {
  id-errorCodes 1 }

id-privacyMarkTooLong OBJECT IDENTIFIER ::= {
  id-errorCodes 2 }

id-unrecognizedSecurityPolicy OBJECT IDENTIFIER ::= {
  id-errorCodes 3 }

id-incorrectKeyProvince OBJECT IDENTIFIER ::= {
  id-errorCodes 4 }

here's what each one means:

  • missingKeyType means all the keying material in a package is the same type, but the key-package-type attribute isn't set in sKeyPkgAttrs [RFC6031]. so it's like "hey, you forgot the type" πŸ₯²
  • privacyMarkTooLong means a classification attribute has a privacy-mark longer than 128 characters. too much tea πŸ«–
  • unrecognizedSecurityPolicy means the security-policy-identifier isn't supported. not on the list, sorry πŸ™…β€β™€οΈ
  • incorrectKeyProvince means the key-province-v2 value in a key package doesn't match the key province constraint of the trust anchor used to validate it. wrong zone, bestie πŸ—ΊοΈ

30. Processing Key Package Attribute Values and CMS Content Constraints 🧠

trust anchors can have constraints for any content type [RFC5934]. when a trust anchor has constraints for the symmetric key package content type or the asymmetric key package content type, those constraints give default values for key package attributes that aren't in the key package. they also define the set of acceptable values for attributes that are there πŸ“‹

when a trust anchor hands off authority by issuing an X.509 certificate, the CMS content constraints certificate extension [RFC6010] can be included to constrain what's allowed. the trust anchor and the X.509 certification path together give default values for missing attributes and define which values are acceptable for attributes that are present πŸ”—

constraints on content type usage are represented as attributes. simple πŸ’œ

the processing procedures for the CMS content constraints certificate extension [RFC6010] are part of validating a signed or authenticated object. those procedures give three output values: cms_constraints, cms_effective_attributes, and cms_default_attributes. object validation MUST be performed before processing the key package contents, and those output values get used during key package processing. these same output values can be generated straight from a trust anchor and the key package when no X.509 certification path is involved in validation 🫢

the cms_effective_attributes gives the set of acceptable values for attributes. every attribute in the key package that matches an entry in cms_effective_attributes MUST contain a value that appears in that entry. attributes that don't match any entry are unconstrained and can hold any value 🌸 matching is done by comparing the attribute object identifier to the object identifier for each entry in cms_effective_attributes.

the cms_default_attributes gives values for attributes that aren't in the key package. if cms_default_attributes has only one value for a particular attribute, that value gets used as if it had been included in the key package itself. but if it has more than one value for the same attribute, the right value is ambiguous, and the key package should be rejected πŸ™ƒ

some attributes can appear in more than one place in the key package, so the attribute definitions include consistency checks. those checks are independent of the constraints checking. on top of the consistency checks, every instance of the attribute MUST be checked against the set of cms_effective_attributes, and the key package MUST be rejected if any attribute value isn't in the set of authorized values. no exceptions, main character energy only πŸ‘‘


31. Attribute Scope πŸ¦‹

this section gives an example symmetric key package so we can talk about the scope of attributes. it's informative, not normative, so it's not a formal part of the spec, more like a friendly walkthrough 🧚 Figure 1 shows the example. everything here applies to a symmetric key package or an asymmetric key package, EXCEPT the key-algorithm attribute, which only applies to a symmetric key package. each component is labeled with a number in parentheses so it's easy to point at:

(1) is the ContentInfo that must be present as the outermost layer of encapsulation. it has no attributes and is only shown for completeness 🎁

(2) is a SignedData content type, which includes six signed attributes. four of those signed attributes are keying material attributes πŸ’–

Okay so, bestie, this part is the big scope roll call πŸ’…βœ¨ It's basically a walkthrough of the nine nested layers (1) through (9), and it tells you which attributes live in which layer and which ones get checked against each other. Let's go 🫢

(3) is a ContentCollection that includes two encapsulated content types: a ContentWithAttributes and an EncryptedKeyPackage. This content type does not provide any attributes πŸŽ€

(4) is a ContentWithAttributes content type. It encapsulates a SignedData content type. Four key material attributes are provided 🌸

(5) is a SignedData content type. It encapsulates a SymmetricKeyPackage content type. Six signed attributes are provided, and four of them are key material attributes πŸ¦‹

(6) is a SymmetricKeyPackage content type, and it includes three key material attributes. Note that the contents of this key package are not encrypted, but the contents are covered by two digital signatures πŸ‘€πŸ”₯

(7) is an EncryptedKeyPackage content type. It encapsulates a SignedData content type. This content type provides one unprotected attribute 🧚

(8) is a SignedData content type. It encapsulates a SymmetricKeyPackage content type. Six signed attributes are provided, and four of them are key material attributes πŸ’œ

(9) is a SymmetricKeyPackage content type, and it includes three key material attributes. Note that the contents of this key package are encrypted. The plaintext keying material is covered by one digital signature, and the ciphertext keying material is covered by another digital signature πŸ”βœ¨


SignedData content type (2) includes six signed attributes, and here's the tea on each one πŸ“

  • The content-type attribute contains id-ct-contentCollection to indicate the type of the encapsulated content, and it has no further scope.
  • The message-digest attribute contains the one-way hash value of the encapsulated content. It is needed to validate the digital signature, and it has no further scope.
  • The classification attribute contains the security label for all of the plaintext in the encapsulated content. Each classification attribute is evaluated separately, and it has no further scope. In general, the values of this attribute will match or dominate the security label values in (4), (5), and (6). The value of this attribute might not match or dominate the security label values in (8) and (9), since those are encrypted. It is possible that these various security label values are associated with different security policies. To avoid the processing complexity associated with policy mapping, comparison is not required πŸ™ˆ
  • The key-package-receivers-v2 attribute indicates the authorized key package receivers, and it has no further scope. The additional instances of key-package-receivers-v2 attribute embedded in (4) are evaluated without regard to the value of the instance in (2).
  • The key-distribution-period attribute contains two date values: doNotDistBefore and doNotDistAfter. These values must match all others within the same scope, which in this example is the key-distribution-period within (4) πŸ“…
  • The key-package-type attribute indicates the format of the key package, and it has no further scope. The key-package-type attribute values within (5) and (8) are evaluated without regard to the value of this attribute.

ContentWithAttributes content type (4) includes four attributes 🌈

  • The classification attribute contains the security label for all of the plaintext in the encapsulated content. Each classification attribute is evaluated separately, and it has no further scope.
  • The TSEC-Nomenclature attribute includes only the shortTitle field, and the value must match all other instances within the same scope, which appear in (5) and (6). Note that the TSEC-Nomenclature attribute values in (8) and (9) are not in the same scope as the TSEC-Nomenclature attribute that appears in (4).
  • The key-package-receivers-v2 attribute indicates the authorized key package receivers, and it has no further scope. The enveloping instance of the key-package-receivers-v2 attribute value in (2) is evaluated without regard to the value of this instance in (4), and it has no effect on the value of this instance in (4).
  • The key-distribution-period attribute contains two date values: doNotDistBefore and doNotDistAfter. These values must match all others within the same scope, which in this example is the key-distribution-period within (2).

SignedData content type (5) includes six signed attributes πŸŽ€

  • The content-type attribute contains id-ct-KP-skeyPackage to indicate the type of the encapsulated content, and it has no further scope.
  • The message-digest attribute contains the one-way hash value of the encapsulated content. It is needed to validate the digital signature, and it has no further scope.
  • The classification attribute contains the security label for all of the plaintext in the encapsulated content. Each classification attribute is evaluated separately, and it has no further scope.
  • The TSEC-Nomenclature attribute includes only the shortTitle field, and the value must match all other instances within the same scope, which appear in (6). Since this is within the scope of (4), these shortTitle field values must match as well. Note that the TSEC-Nomenclature attribute values in (8) and (9) are not in the same scope.
  • The key-purpose attribute specifies the purpose of the key material. All occurrences within the scope must have the same value. However, in this example, there are no other occurrences within the scope. The key-purpose attribute value within (8) is evaluated without regard to the value of this attribute.
  • The key-package-type attribute indicates the format of the key package, and it has no further scope. The key-package-type attribute values within (2) and (8) are evaluated without regard to the value of this attribute.

SymmetricKeyPackage content type (6) includes three keying material attributes, which could appear in the sKeyPkgAttrs or sKeyAttrs fields πŸ”‘

  • The key-algorithm attribute includes only the keyAlg field, and it must match all other occurrences within the same scope. However, there are no other key-algorithm attribute occurrences in the same scope. The key-algorithm attribute value in (9) is not in the same scope.
  • The classification attribute contains the security label for all of the plaintext in the key package. Each classification attribute is evaluated separately, and it has no further scope.
  • The TSEC-Nomenclature attribute includes the shortTitle field as well as some of the optional fields. The shortTitle field value must match the values in (4) and (5), since this content type is within their scope. Note that the TSEC-Nomenclature attribute values in (8) and (9) are not in the same scope.

EncryptedKeyPackage content type (7) includes one unprotected attribute, and the encryption will prevent any intermediary that does not have the ability to decrypt the content from making any consistency checks on (8) and (9) πŸ™…β€β™€οΈ

  • The content-decryption-key-identifier attribute identifies the key that is needed to decrypt the encapsulated content, and it has no further scope.

SignedData content type (8) includes six signed attributes πŸ’–

  • The content-type attribute contains id-ct-KP-skeyPackage to indicate the type of the encapsulated content, and it has no further scope.
  • The message-digest attribute contains the one-way hash value of the encapsulated content. It is needed to validate the digital signature, and it has no further scope.
  • The classification attribute contains the security label for content. Each classification attribute is evaluated separately, and it has no further scope.
  • The TSEC-Nomenclature attribute includes only the shortTitle field, and the value must match all other instances within the same scope, which appear in (9). Note that the TSEC-Nomenclature attribute values in (4), (5), and (6) are not in the same scope.
  • The key-purpose attribute specifies the purpose of the key material. All occurrences within the scope must have the same value. However, in this example, there are no other occurrences within the scope. The key-purpose attribute value within (5) is evaluated without regard to the value of this attribute.
  • The key-package-type attribute indicates the format of the key package, and it has no further scope. The key-package-type attribute values within (2) and (5) are evaluated without regard to the value of this attribute.

SymmetricKeyPackage content type (9) includes three keying material attributes, which could appear in the sKeyPkgAttrs or sKeyAttrs fields πŸ”

  • The key-algorithm attribute includes only the keyAlg field, and it must match all other occurrences within the same scope. However, there are no other key-algorithm attribute occurrences in the same scope. The key-algorithm attribute value in (6) is not in the same scope.
  • The classification attribute contains the security label for all of the plaintext in the key package. Each classification attribute is evaluated separately, and it has no further scope.
  • The TSEC-Nomenclature attribute includes the shortTitle field as well as some of the optional fields. The shortTitle field value must match the values in (8), since this content type is within its scope. Note that the TSEC-Nomenclature attributes values in (4), (5), and (6) are not in the same scope.

In summary, the scope of an attribute includes the encapsulated content of the CMS content type in which it appears, and some attributes also require consistency checks with other instances that appear within the encapsulated content. Proper recognition of scope is required to accurately perform attribute processing 🎯✨

Okay bestie, the Figure 1 diagram is the last bit of section 31, so we're picking up right where it left off πŸ¦‹

   +------------------------------------------------------------------+
   | ContentInfo (1)                                                  |
   |+----------------------------------------------------------------+|
   || SignedData (2)                                                 ||
   ||+--------------------------------------------------------------+||
   ||| ContentCollection (3)                                        |||
   |||+-----------------------------++-----------------------------+|||
   |||| ContentWithAttributes (4)   || EncryptedKeyPackage (7)     ||||
   ||||+---------------------------+||+---------------------------+||||
   ||||| SignedData (5)            |||| SignedData (8)            |||||
   |||||+-------------------------+||||+-------------------------+|||||
   |||||| SymmetricKeyPackage (6) |||||| SymmetricKeyPackage (9) ||||||
   |||||| Attributes:             |||||| Attributes:             ||||||
   ||||||  Key Algorithm          ||||||  Key Algorithm          ||||||
   ||||||  Classification         ||||||  Classification         ||||||
   ||||||  TSEC-Nomenclature      ||||||  TSEC-Nomenclature      ||||||
   |||||+-------------------------+||||+-------------------------+|||||
   ||||| Attributes:               |||| Attributes:               |||||
   |||||  Content Type             ||||  Content Type             |||||
   |||||  Message Digest           ||||  Message Digest           |||||
   |||||  Classification           ||||  Classification           |||||
   |||||  TSEC-Nomenclature        ||||  TSEC-Nomenclature        |||||
   |||||  Key Purpose              ||||  Key Purpose              |||||
   |||||  Key Package Type         ||||  Key Package Type         |||||
   ||||+-------------------------- +||+---------------------------+||||
   |||| Attributes:                 || Unprotect Attributes:       ||||
   ||||  Classification             ||  Content Decrypt Key ID     ||||
   ||||  TSEC-Nomenclature          |+-----------------------------+|||
   ||||  Key Package Receivers      |                               |||
   ||||  Key Distribution Period    |                               |||
   |||+-----------------------------+                               |||
   ||+--------------------------------------------------------------+||
   || Attributes:                                                    ||
   ||  Content Type                                                  ||
   ||  Message Digest                                                ||
   ||  Classification                                                ||
   ||  Key Package Receivers                                         ||
   ||  Key Distribution Period                                       ||
   ||  Key Package Type                                              ||
   |+----------------------------------------------------------------+|
   +------------------------------------------------------------------+

Figure 1: Example Illustrating Scope of Attributes


32. Security Considerations ✨

Okay, the security section is serious business, so let's be real πŸ”₯ Most of this spec is about the syntax and semantics of key package attributes. It leans on a bunch of other specs, especially [RFC2634], [RFC4073], [RFC4108], [RFC5652], [RFC5911], [RFC5912], [RFC5958], [RFC6010], and [RFC6031]. Their security considerations apply here too, no cap πŸ’… Also, cryptographic algorithms get used with CMS to protect content types, as specified in [RFC5959], [RFC6160], [RFC6161], and [RFC6162], so those docs' security considerations count here as well 🫢

This spec also relies on [RFC5280] for the syntax and semantics of X.509 certificates. Digital signatures give you data integrity or data origin authentication, and encryption gives you confidentiality. Iconic duo πŸ‘‘

Security factors outside the scope of this spec massively affect the assurance you actually get 😭 The way Certification Authorities (CAs) validate that a subject identity is bound to their public key hugely affects how much trust a certificate deserves. This is especially important when CAs are issuing certificates to other CAs. Main character energy for the CA process, honestly 🌈

⚠️ The CMS AuthenticatedData content type MUST be used with care, because a Message Authentication Code (MAC) is involved. The same key is needed to generate the MAC and to validate it. So any party that has access to the key needed to validate the MAC can make a replacement that will be accepted by other recipients. Yikes, that's a whole vibe check πŸ’€

In some situations, returning really detailed error info can give an attacker insight into the security processing πŸ™ˆ So where that's a concern, the implementation should return the most generic error code that is appropriate. BUT detailed error codes are super helpful during development, debugging, and interoperability testing, so implementations may want a way to configure whether they use generic or detailed error codes. Choose your fighter, bestie πŸŽ€

33. References 🌸

33.1. Normative References

33.2. Informative References

  • [RFC5934] Housley, R., Ashmore, S., and C. Wallace, "Trust Anchor Management Protocol (TAMP)", RFC 5934, DOI 10.17487/RFC5934, August 2010, <http://www.rfc-editor.org/info/rfc5934>.
  • [X.411] ITU-T, "Information technology - Message Handling Systems (MHS): Message Transfer System: Abstract Service Definition and Procedures", ITU-T Recommendation X.411 | ISO/IEC 10021-4:1999, 1999.

Appendix A. ASN.1 Module 🧚

Okay, the appendix is where the ASN.1 lives, and it is giving structure ✨

   KMAttributes2012
     { joint-iso-itu-t(2) country(16) us(840) organization(1)
       gov(101) dod(2) infosec(1) modules(0) 39 }

   DEFINITIONS IMPLICIT TAGS ::=

   BEGIN

   -- EXPORT ALL

   IMPORTS

   -- From [RFC5911]

   aa-communityIdentifiers, CommunityIdentifier
     FROM CMSFirmwareWrapper-2009
       { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
         smime(16) modules(0) id-mod-cms-firmware-wrap-02(40) }

   -- From [RFC5911]

okay the ASN.1 module keeps going and it's giving pure precision πŸ’…πŸŽ€

   aa-contentHint, ESSSecurityLabel, id-aa-securityLabel
     FROM ExtendedSecurityServices-2009
       { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
         smime(16) modules(0) id-mod-ess-2006-02(42) }

   -- From [RFC5911] [RFC5912]

   AlgorithmIdentifier{}, SMIME-CAPS, ParamOptions, KEY-WRAP
     FROM AlgorithmInformation-2009
       { iso(1) identified-organization(3) dod(6) internet(1)
         security(5) mechanisms(5) pkix(7) id-mod(0)
         id-mod-algorithmInformation-02(58) }

   -- From [RFC5912]

   Name, Certificate
     FROM PKIX1Explicit-2009
       { iso(1) identified-organization(3) dod(6) internet(1)
         security(5) mechanisms(5) pkix(7) id-mod(0)
         id-mod-pkix1-explicit-02(51) }

   -- From [RFC5912]

   GeneralNames, SubjectInfoAccessSyntax, id-pe-subjectInfoAccess
     FROM PKIX1Implicit-2009
       { iso(1) identified-organization(3) dod(6) internet(1)
         security(5) mechanisms(5) pkix(7) id-mod(0)
         id-mod-pkix1-implicit-02(59) }

   -- FROM [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 [RFC6010]

   CMSContentConstraints
     FROM CMSContentConstraintsCertExtn
       { iso(1) identified-organization(3) dod(6) internet(1)
          security(5) mechanisms(5) pkix(7) id-mod(0)
          cmsContentConstr-93(42) }

   -- From [RFC6268]

   aa-binarySigningTime, BinaryTime
     FROM BinarySigningTimeModule-2010
       { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
         smime(16) modules(0) id-mod-binSigningTime-2009(55) }

   -- From [RFC6268]

   CertificateChoices, CertificateSet, Attribute {},
   aa-contentType, aa-messageDigest
     FROM CryptographicMessageSyntax-2010
       { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
         smime(16) modules(0) id-mod-cms-2009(58) }

   -- From [RFC7191]

   aa-keyPackageIdentifierAndReceiptRequest, SIREntityName
     FROM KeyPackageReceiptAndErrorModuleV2
       { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
         smime(16) modules(0) id-mod-keyPkgReceiptAndErrV2(63) }

   -- From [X.509]

   certificateExactMatch
     FROM CertificateExtensions
       { joint-iso-itu-t ds(5) module(1) certificateExtensions(26) 4 }

   ;

   -- ATTRIBUTES

   -- Replaces SignedAttributesSet information object set from
   -- [RFC6268].

   SignedAttributesSet ATTRIBUTE ::= {
     aa-contentType                           |
     aa-messageDigest                         |
     aa-contentHint                           |
     aa-communityIdentifiers                  |
     aa-binarySigningTime                     |
     aa-keyProvince-v2                        |
     aa-keyPackageIdentifierAndReceiptRequest |
     aa-manifest                              |
     aa-keyAlgorithm                          |
     aa-userCertificate                       |
     aa-keyPackageReceivers-v2                |
     aa-tsecNomenclature                      |
     aa-keyPurpose                            |
     aa-keyUse                                |
     aa-transportKey                          |
     aa-keyDistributionPeriod                 |
     aa-keyValidityPeriod                     |
     aa-keyDurationPeriod                     |
     aa-classificationAttribute               |
     aa-keyPackageType                        |
     aa-pkiPath                               |
     aa-usefulCertificates,
     ... }

   -- Replaces UnsignedAttributes from [RFC6268].

   UnsignedAttributes ATTRIBUTE ::= {
      ...
      }

   -- Replaces UnprotectedEnvAttributes from [RFC6268].

   UnprotectedEnvAttributes ATTRIBUTE ::= {
     aa-contentDecryptKeyIdentifier |
     aa-certificatePointers         |
     aa-cRLDistributionPoints,
     ...
     }

   -- Replaces UnprotectedEncAttributes from [RFC6268].

   UnprotectedEncAttributes ATTRIBUTE ::= {
     aa-certificatePointers |
     aa-cRLDistributionPoints,
     ...
     }

   -- Replaces AuthAttributeSet from [RFC6268]

   AuthAttributeSet ATTRIBUTE ::= {
     aa-contentType                           |
     aa-messageDigest                         |
     aa-contentHint                           |
     aa-communityIdentifiers                  |
     aa-keyProvince-v2                        |
     aa-binarySigningTime                     |
     aa-keyPackageIdentifierAndReceiptRequest |
     aa-manifest                              |
     aa-keyAlgorithm                          |
     aa-userCertificate                       |
     aa-keyPackageReceivers-v2                |
     aa-tsecNomenclature                      |
     aa-keyPurpose                            |
     aa-keyUse                                |
     aa-transportKey                          |
     aa-keyDistributionPeriod                 |
     aa-keyValidityPeriod                     |
     aa-keyDurationPeriod                     |
     aa-classificationAttribute               |
     aa-keyPackageType                        |
     aa-pkiPath                               |
     aa-usefulCertificates,
     ... }

   -- Replaces UnauthAttributeSet from [RFC6268]

   UnauthAttributeSet ATTRIBUTE ::= {
     ...
     }

   -- Replaces AuthEnvDataAttributeSet from [RFC6268]

   AuthEnvDataAttributeSet ATTRIBUTE ::= {
     aa-certificatePointers |
     aa-cRLDistributionPoints,
     ...
     }

    -- Replaces UnauthEnvDataAttributeSet from [RFC6268]

   UnauthEnvDataAttributeSet ATTRIBUTE ::= {
     ...
     }

   -- Replaces OneAsymmetricKeyAttributes from [RFC5958]

   OneAsymmetricKeyAttributes ATTRIBUTE ::= {
     aa-userCertificate            |
     aa-tsecNomenclature           |
     aa-keyPurpose                 |
     aa-keyUse                     |
     aa-transportKey               |
     aa-keyDistributionPeriod      |
     aa-keyValidityPeriod          |
     aa-keyDurationPeriod          |
     aa-classificationAttribute    |
     aa-splitIdentifier            |
     aa-signatureUsage-v3          |
     aa-otherCertificateFormats    |
     aa-pkiPath                    |
     aa-usefulCertificates,
     ... }

   -- Replaces SKeyPkgAttributes from [RFC6031]

   SKeyPkgAttributes ATTRIBUTE ::= {
     aa-keyAlgorithm                |
     aa-tsecNomenclature            |
     aa-keyPurpose                  |
     aa-keyUse                      |
     aa-keyDistributionPeriod       |
     aa-keyValidityPeriod           |
     aa-keyDurationPeriod           |
     aa-classificationAttribute     |
     aa-keyWrapAlgorithm            |
     aa-contentDecryptKeyIdentifier,
     ... }

   -- Replaces SKeyAttributes from [RFC6031]

   SKeyAttributes ATTRIBUTE ::= {
     aa-keyAlgorithm                |
     aa-tsecNomenclature            |
     aa-keyPurpose                  |
     aa-keyUse                      |
     aa-keyDistributionPeriod       |
     aa-keyValidityPeriod           |
     aa-keyDurationPeriod           |
     aa-classificationAttribute     |
     aa-splitIdentifier             |
     aa-keyWrapAlgorithm            |
     aa-contentDecryptKeyIdentifier,
     ... }

   -- Replaces ContentAttributeSet from [RFC6268]

   ContentAttributeSet ATTRIBUTE ::= {
     aa-communityIdentifiers                  |
     aa-keyPackageIdentifierAndReceiptRequest |
     aa-keyAlgorithm                          |
     aa-keyPackageReceivers-v2                |
     aa-tsecNomenclature                      |
     aa-keyPurpose                            |
     aa-keyUse                                |
     aa-transportKey                          |
     aa-keyDistributionPeriod                 |
     aa-transportKey                          |
     aa-keyDistributionPeriod                 |
     aa-keyValidityPeriod                     |
     aa-keyDurationPeriod                     |
     aa-classificationAttribute               |
     aa-keyPackageType                        |
     aa-pkiPath                               |
     aa-usefulCertificates,
     ... }

   -- Content Type, Message Digest, Content Hint, and Binary Signing
   -- Time are imported from [RFC6268].
   -- Community Identifiers is imported from [RFC5911].

   -- Key Province

   aa-keyProvince-v2 ATTRIBUTE ::= {
     TYPE KeyProvinceV2
     IDENTIFIED BY id-aa-KP-keyProvinceV2 }

   id-aa-KP-keyProvinceV2 OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) attributes(5) 71 }

   KeyProvinceV2 ::= OBJECT IDENTIFIER

   -- Manifest Attribute

   aa-manifest ATTRIBUTE ::= {
     TYPE Manifest
     IDENTIFIED BY id-aa-KP-manifest }

   id-aa-KP-manifest OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) attributes(5) 72 }

   Manifest ::= SEQUENCE SIZE (1..MAX) OF ShortTitle

   -- Key Algorithm Attribute

   aa-keyAlgorithm ATTRIBUTE ::= {
     TYPE KeyAlgorithm
     IDENTIFIED BY id-kma-keyAlgorithm }

   id-kma-keyAlgorithm  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 1 }

   KeyAlgorithm ::= SEQUENCE {
     keyAlg            OBJECT IDENTIFIER,
     checkWordAlg  [1] OBJECT IDENTIFIER OPTIONAL,
     crcAlg        [2] OBJECT IDENTIFIER OPTIONAL }

   -- User Certificate Attribute

   aa-userCertificate ATTRIBUTE ::= {
     TYPE Certificate
     EQUALITY MATCHING RULE certificateExactMatch
     IDENTIFIED BY id-at-userCertificate }

   id-at-userCertificate OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) ds(5) attributes(4) 36 }

   -- Key Package Receivers Attribute

   aa-keyPackageReceivers-v2 ATTRIBUTE ::= {
     TYPE KeyPkgReceiversV2
     IDENTIFIED BY id-kma-keyPkgReceiversV2 }

   id-kma-keyPkgReceiversV2  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 16 }

   KeyPkgReceiversV2 ::= SEQUENCE SIZE (1..MAX) OF KeyPkgReceiver

   KeyPkgReceiver ::= CHOICE {
     sirEntity  [0] SIREntityName,
     community  [1] CommunityIdentifier }

   -- TSEC Nomenclature Attribute

   aa-tsecNomenclature ATTRIBUTE ::= {
     TYPE TSECNomenclature
     IDENTIFIED BY id-kma-TSECNomenclature }

   id-kma-TSECNomenclature  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 3 }

   TSECNomenclature ::= SEQUENCE {
     shortTitle  ShortTitle,
     editionID   EditionID OPTIONAL,
     registerID  RegisterID OPTIONAL,
     segmentID   SegmentID OPTIONAL }

   ShortTitle ::= PrintableString

   EditionID ::= CHOICE {
     char CHOICE {
       charEdition      [1] CharEdition,
       charEditionRange [2] CharEditionRange },
     num CHOICE {
       numEdition       [3] NumEdition,
       numEditionRange  [4] NumEditionRange } }

   CharEdition ::= PrintableString

   CharEditionRange ::= SEQUENCE {
     firstCharEdition  CharEdition,
     lastCharEdition   CharEdition }

   NumEdition ::= INTEGER (0..308915776)

   NumEditionRange ::= SEQUENCE {
     firstNumEdition  NumEdition,
     lastNumEdition   NumEdition }

   RegisterID ::= CHOICE {
     register       [5] Register,
     registerRange  [6] RegisterRange }

   Register ::= INTEGER (0..2147483647)

   RegisterRange ::= SEQUENCE {
     firstRegister  Register,
     lastRegister   Register }

   SegmentID ::= CHOICE {
     segmentNumber  [7] SegmentNumber,
     segmentRange   [8] SegmentRange }

   SegmentNumber ::= INTEGER (1..127)

   SegmentRange ::= SEQUENCE {
     firstSegment  SegmentNumber,
     lastSegment   SegmentNumber }

   -- Key Purpose Attribute

   aa-keyPurpose ATTRIBUTE ::= {
     TYPE KeyPurpose
     IDENTIFIED BY id-kma-keyPurpose }

Okay, the module keeps going, and this is where the good stuff lives πŸŽ€

   id-kma-keyPurpose  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 13 }

   KeyPurpose ::= ENUMERATED {
     n-a    (0),   -- Not Applicable
     a     (65),   -- Operational
     b     (66),   -- Compatible Multiple Key
     l     (76),   -- Logistics Combinations
     m     (77),   -- Maintenance
     r     (82),   -- Reference
     s     (83),   -- Sample
     t     (84),   -- Training
     v     (86),   -- Developmental
     x     (88),   -- Exercise
     z     (90),   -- "On the Air" Testing
     ... -- Expect additional key purpose values -- }

   -- Key Use Attribute

   aa-keyUse ATTRIBUTE ::= {
     TYPE KeyUse
     IDENTIFIED BY id-kma-keyUse }

   id-kma-keyUse  OBJECT IDENTIFIER ::=
      { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
        dod(2) infosec(1) keying-material-attributes(13) 14 }

   KeyUse ::= ENUMERATED {
     n-a    (0),    -- Not Applicable
     ffk    (1),    -- FIREFLY/CROSSTALK Key (Basic Format)
     kek    (2),    -- Key Encryption Key
     kpk    (3),    -- Key Production Key
     msk    (4),    -- Message Signature Key
     qkek   (5),    -- QUADRANT Key Encryption Key
     tek    (6),    -- Traffic Encryption Key
     tsk    (7),    -- Transmission Security Key
     trkek  (8),    -- Transfer Key Encryption Key
     nfk    (9),    -- Netted FIREFLY Key
     effk  (10),    -- FIREFLY Key (Enhanced Format)
     ebfk  (11),    -- FIREFLY Key (Enhanceable Basic Format)
     aek   (12),    -- Algorithm Encryption Key
     wod   (13),    -- Word of Day
     kesk (246),    -- Key Establishment Key
     eik  (247),    -- Entity Identification Key
     ask  (248),    -- Authority Signature Key
     kmk  (249),    -- Key Modifier Key
     rsk  (250),    -- Revocation Signature Key
     csk  (251),    -- Certificate Signature Key
     sak  (252),    -- Symmetric Authentication Key
     rgk  (253),    -- Random Generation Key
     cek  (254),    -- Certificate Encryption Key
     exk  (255),    -- Exclusion Key
     ... -- Expect additional key use values -- }

   -- Transport Key Attribute

   aa-transportKey ATTRIBUTE ::= {
     TYPE TransOp
     IDENTIFIED BY id-kma-transportKey }

   id-kma-transportKey  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 15 }

   TransOp ::= ENUMERATED {
     transport    (1),
     operational  (2) }

   -- Key Distribution Period Attribute

   aa-keyDistributionPeriod ATTRIBUTE ::= {
     TYPE KeyDistPeriod
     IDENTIFIED BY id-kma-keyDistPeriod }

   id-kma-keyDistPeriod  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 5 }

   KeyDistPeriod ::= SEQUENCE {
     doNotDistBefore  [0] BinaryTime OPTIONAL,
     doNotDistAfter       BinaryTime }

   -- Key Validity Period Attribute

   aa-keyValidityPeriod ATTRIBUTE ::= {
     TYPE KeyValidityPeriod
     IDENTIFIED BY id-kma-keyValidityPeriod }

   id-kma-keyValidityPeriod  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 6 }

   KeyValidityPeriod ::= SEQUENCE {
     doNotUseBefore  BinaryTime,
     doNotUseAfter   BinaryTime OPTIONAL }

   -- Key Duration Attribute

   aa-keyDurationPeriod ATTRIBUTE ::= {
     TYPE KeyDuration
     IDENTIFIED BY id-kma-keyDuration }

   id-kma-keyDuration  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 7 }

   KeyDuration ::= CHOICE {
     hours   [0] INTEGER (1..ub-KeyDuration-hours),
     days        INTEGER (1..ub-KeyDuration-days),
     weeks   [1] INTEGER (1..ub-KeyDuration-weeks),
     months  [2] INTEGER (1..ub-KeyDuration-months),
     years   [3] INTEGER (1..ub-KeyDuration-years) }

   ub-KeyDuration-hours  INTEGER ::=  96
   ub-KeyDuration-days   INTEGER ::= 732
   ub-KeyDuration-weeks  INTEGER ::= 104
   ub-KeyDuration-months INTEGER ::=  72
   ub-KeyDuration-years  INTEGER ::= 100
   -- Classification Attribute

   -- The attribute syntax is imported from [RFC6268].  The term
   -- "classification" is used in this document, but the term "security
   -- label" is used in [RFC2634].  The terms have the same meaning.

   aa-classificationAttribute ATTRIBUTE ::= {
     TYPE Classification
     IDENTIFIED BY id-aa-KP-classification }

   id-aa-KP-classification OBJECT IDENTIFIER ::= id-aa-securityLabel

   Classification ::= ESSSecurityLabel

   id-enumeratedRestrictiveAttributes OBJECT IDENTIFIER ::=
     { 2 16 840 1 101 2 1 8 3 4 }

   id-enumeratedPermissiveAttributes OBJECT IDENTIFIER ::=
     { 2 16 840 1 101 2 1 8 3 1 }

   EnumeratedTag ::= SEQUENCE {
     tagName          OBJECT IDENTIFIER,
     attributeList    SET OF SecurityAttribute }

   SecurityAttribute ::= INTEGER (0..MAX)

   -- Split Identifier Attribute

   aa-splitIdentifier ATTRIBUTE ::= {
     TYPE SplitID
     IDENTIFIED BY id-kma-splitID }

   id-kma-splitID  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 11 }

   SplitID ::= SEQUENCE {
     half        ENUMERATED { a(0), b(1) },
     combineAlg  AlgorithmIdentifier
                   {COMBINE-ALGORITHM, {CombineAlgorithms}}  OPTIONAL }

   COMBINE-ALGORITHM ::= CLASS {
     &id                OBJECT IDENTIFIER UNIQUE,
     &Params            OPTIONAL,
     &paramPresence     ParamOptions DEFAULT absent,
     &smimeCaps         SMIME-CAPS OPTIONAL
   }
   WITH SYNTAX {
     IDENTIFIER &id
     [PARAMS [TYPE &Params] ARE &paramPresence]
     [SMIME-CAPS &smimeCaps]
   }

   CombineAlgorithms COMBINE-ALGORITHM ::= {
     ...
     }

   -- Key Package Type Attribute

   aa-keyPackageType ATTRIBUTE ::= {
     TYPE KeyPkgType
     IDENTIFIED BY id-kma-keyPkgType }

   id-kma-keyPkgType  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 12 }

   KeyPkgType ::= OBJECT IDENTIFIER

   -- Signature Usage Attribute

   aa-signatureUsage-v3 ATTRIBUTE ::= {
     TYPE SignatureUsage
     IDENTIFIED BY id-kma-sigUsageV3 }

   id-kma-sigUsageV3  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 22 }

   SignatureUsage ::= CMSContentConstraints

   -- Other Certificate Format Attribute

   aa-otherCertificateFormats ATTRIBUTE ::= {
     TYPE CertificateChoices
     IDENTIFIED BY id-kma-otherCertFormats }

   id-kma-otherCertFormats OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 19 }

   -- PKI Path Attribute

   aa-pkiPath ATTRIBUTE ::= {
     TYPE PkiPath
     IDENTIFIED BY id-at-pkiPath }

   id-at-pkiPath OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) ds(5) attributes(4) 70 }

   PkiPath ::= SEQUENCE SIZE (1..MAX) OF Certificate

   -- Useful Certificates Attribute

   aa-usefulCertificates ATTRIBUTE ::= {
     TYPE CertificateSet
     IDENTIFIED BY id-kma-usefulCerts }

   id-kma-usefulCerts OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 20 }

   -- Key Wrap Attribute

   aa-keyWrapAlgorithm ATTRIBUTE ::= {
     TYPE AlgorithmIdentifier{KEY-WRAP, {KeyEncryptionAlgorithmSet}}
     IDENTIFIED BY id-kma-keyWrapAlgorithm }

   id-kma-keyWrapAlgorithm OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) keying-material-attributes(13) 21 }

   KeyEncryptionAlgorithmSet KEY-WRAP ::= { ... }

   -- Content Decryption Key Identifier Attribute

   aa-contentDecryptKeyIdentifier ATTRIBUTE ::= {
     TYPE ContentDecryptKeyID
     IDENTIFIED BY id-aa-KP-contentDecryptKeyID }

   id-aa-KP-contentDecryptKeyID OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) attributes(5) 66 }

   ContentDecryptKeyID::= OCTET STRING
   -- Certificate Pointers Attribute

   aa-certificatePointers ATTRIBUTE ::= {
     TYPE SubjectInfoAccessSyntax
     IDENTIFIED BY id-pe-subjectInfoAccess }

   -- CRL Pointers Attribute

   aa-cRLDistributionPoints ATTRIBUTE ::= {
     TYPE GeneralNames
     IDENTIFIED BY id-aa-KP-crlPointers }

   id-aa-KP-crlPointers  OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) attributes (5) 70 }

   -- ExtendedErrorCodes

   id-errorCodes OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
       dod(2) infosec(1) errorCodes(22) }

   id-missingKeyType OBJECT IDENTIFIER ::= {
     id-errorCodes 1 }

   id-privacyMarkTooLong OBJECT IDENTIFIER ::= {
     id-errorCodes 2 }

   id-unrecognizedSecurityPolicy OBJECT IDENTIFIER ::= {
     id-errorCodes 3 }

   END

Authors' Addresses ✨

Paul Timmel National Information Assurance Research Laboratory National Security Agency

Email: pstimme@nsa.gov

Russ Housley Vigil Security, LLC 918 Spring Knoll Drive Herndon, VA 20170 United States

Email: housley@vigilsec.com

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

Email: turners@ieca.com

πŸ“¦ where this page comes from