DRAFT S/MIME Freeware Library Application Programming Interface Version 0.3 27 March 1998 Produced By: J.G. Van Dyke & Associates, Inc. 6550 Rock Spring Dr, Suite 360 Bethesda, MD 20817 http://www.jgvandyke.com Revision History Table of Contents 1. SCOPE 1 1.1. IDENTIFICATION 1 1.2. SYSTEM OVERVIEW 1 1.3 DOCUMENT OVERVIEW 1 2. REFERENCED DOCUMENTS 2 3. DEFINITION OF TERMS 3 4. APPLICATION-SFL INTERACTION CONCEPTS 3 4.1. SFL RESPONSIBILITIES: 3 4.2. APPLICATION RESPONSIBILITIES: 4 5. SFL C API 4 6. SFL C++ API 5 6.1 C++ INTRODUCTION 5 6.1.1 C++ General Software Conventions 5 6.1.2. SFL C++ Classes Introduction 6 6.2 THE HIGH LEVEL MESSAGE CLASSES 9 6.2.1 CSM_SignMsg 9 6.2.2 CSM_VerifyMsg 14 6.2.3 CSM_EncryptMsg 20 6.2.4 CSM_DecryptMsg 25 6.2.5 CSM_ContentInfoMsg 29 6.2.6 CSM_AddSignMsg 30 6.2.7 CSM_VerifyReceiptMsg 30 6.3 THE LOW LEVEL MESSAGE CLASSES 31 6.3.1 CSM_SignData 31 6.3.2 CSM_VerifyData 31 6.3.3 CSM_EncryptData 33 6.3.4 CSM_DecryptData 33 6.3.5 CSM_VerifyReceiptData Error! Bookmark not defined. 6.4 THE LOW LEVEL COMPONENT CLASSES 34 6.4.1 CSM_MsgAttributes 34 6.4.2 CSM_Attrib 35 6.4.3 CSM_CounterSignature 36 6.4.4 CSM_ReceiptRequest 37 6.4.5 CSM_ContentHints 37 6.4.6 CSM_SecLbl 37 6.4.7 CSM_MlLst 38 6.4.8 CSM_GeneralAsn 38 6.4.9 CSM_Capabilities 38 6.4.10 CSM_CntType 38 6.4.11 CSM_MsgSignerInfos 39 6.4.12 CSM_MsgSignerInfo 39 6.4.13 CSM_MsgCertCrls 40 6.4.14 CSM_CertificateChoice 41 6.4.15 CSM_List 42 6.4.16 CSM_CommonData 43 6.4.17 CSM_Content 44 6.4.18 CSM_IssuerAndSerialNumber 45 6.4.19 CSM_Recipient 45 6.4.20 CSM_UserKeyMaterial 46 6.4.21 CSM_OriginatorInfo 46 6.4.22 CSM_Buffer 46 6.4.23 CSM_OID 49 6.5 THE CSMIME LIBRARY CLASS 51 6.5.1 CSMIME Construction Members 51 6.5.2 CSMIME Attribute Members 51 6.6 THE CSM_CSINST CLASS 53 6.6.1 CSM_CSInst Construction Members 53 6.6.2 CSM_CSInst Attribute Members 53 6.7 THE ERROR HANDLING CLASS, CSM_ERRORBUF 54 6.7.1 CSM_ErrorBuf Construction Members 54 6.7.2 CSM_ErrorBuf Attribute Members 55 7. ERROR HANDLING CONVENTIONS 55 8. SFL CRYPTOGRAPHIC TOKEN INTERFACE (CTI) LIBRARIES 55 8.1. SFL SM_BSAFE CTI LIBRARY 55 8.2. SFL SM_CRYPTO ++ CTI LIBRARY 55 8.3. SFL SM_FORTEZZA CTI LIBRARY 56 9. POSSIBLE FUTURE ENHANCEMENTS 56 10. POINT OF CONTACT 56 APPENDIX A. SENDING AND RECEIVING S/MIME MESSAGES 57 A.1. SIGNED-ONLY S/MIME MESSAGE 57 A.1.1. Sending a Signed-Only S/MIME Message 57 A.1.2. Receiving a Signed-Only S/MIME Message 58 A.2. ENCRYPTED-ONLY S/MIME MESSAGE 58 A.2.1. Sending an Encrypted-Only S/MIME Message. 59 A.2.2. Receiving an Encrypted-Only S/MIME Message 59 A.3. SIGNED AND ENCRYPTED S/MIME MESSAGE 60 A.3.1. Sending a Signed and Encrypted S/MIME Message 60 A.3.2. Receiving a Signed and Encrypted S/MIME Message 61 A.4. SIGNED/ENCRYPTED/SIGNED S/MIME MESSAGE 62 A.4.1. MLA Sending Signed/Encrypted/Signed S/MIME Message 63 A.4.2. Receiving a Signed/Encrypted/Signed S/MIME Message 65 A.5. OTHER TYPES OF MESSAGES 66 A.6. S/MIME SIGNED RECEIPT 67 A.6.1. Validating an S/MIME SignedData/Receipt 67 1. Scope 1.1. Identification This draft document specifies the Application Programming Interface (API) for the Secure/Multipurpose Internet Mail Extensions (S/MIME) Freeware Library (SFL) being developed by J.G. Van Dyke and Associates, Inc (VDA). 1.2. System Overview The SFL is a reference implementation of the Cryptographic Message Syntax [CMS] that is the basis for the S/MIME Version 3 Message Specification [SMIME3]. CMS is based on the Public Key Cryptography Standard #7 [PKCS7] specification. In conjunction with CMS, the SFL implements the Enhanced Security Services for S/MIME [ESS] that provides Message Security Protocol 4.0 [MSP] equivalent security features such as: signed receipts, security labels, algorithm independence and Mail List (ML) Expansion History information. The MSP 4.0 specification is also known as [ACP120]. It is anticipated that the Internet Engineering Task Force (IETF) will adopt [CMS], [ESS] and [SMIME3] as Internet standard specifications. Organizations can use the SFL as part of their S/MIME applications without paying any royalties or licensing fees. It is being provided at no cost to encourage organizations to include MSP-equivalent optional security features in their commercial S/MIME v3 products and other products that use CMS. It facilitates the use of both commercial and US Government cryptographic algorithms. It can be used in conjunction with external cryptographic libraries to provide the following security services: - authentication, data integrity and proof of origin using digital signatures; - authenticated proof of delivery using digitally signed receipts; and - confidentiality using encryption (note: some key management algorithms, such as the Key Exchange Algorithm (KEA), also provide data origin authentication). The SFL uses the freeware SNACC Abstract Syntax Notation.1 (ASN.1) Library. 1.3 Document Overview [CMS] and [ESS] should be reviewed before reading this document. The SFL Software Design Description (SDD) describes the functionality and high-level design of the SFL. The SDD should be reviewed prior to reading this document. This API describes the SFL functions, data types and detailed interaction with the application. The target audience is the set of developers who are creating applications that require CMS/ESS security services. This draft API will be updated as needed as changes are made to [CMS] and [ESS]. It will not be finalized until those documents are accepted by the IETF as final or stable draft specifications. A Software Maintenance Document (SMD) will be written which will include information required to enhance and maintain the SFL such as integrating additional cryptographic libraries. There are no restrictions on the use or distribution of this document. 2. Referenced Documents [ACP120] Allied Communications Publication 120, Common Security Protocol, Oct 1997. [CMAPI] Certificate Management API, http://www.armadillo.huntsville.al.us/software/certmgmt/index.html. [CMS] Cryptographic Message Syntax, Internet Draft, March 1998, ftp://ds.internic.net/internet-drafts/draft-ietf-smime-cms-04.txt. [ESS] Enhanced Security Services, Internet Draft, March 12 1998, ftp://ds.internic.net/internet-drafts/draft-ietf-smime-ess-04.txt. [MSP] Message Security Protocol 4.0, SDN.701, Rev A, 1997-02-06, http://www.armadillo.huntsville.al.us/Fortezza_docs/missi2.html#specs. [PKCS7] Public Key Cryptography Standard #7 v1.5, Cryptographic Message Syntax RFC 2315; http://www.imc.org/smime-pgpmime.html. [PKCS8] Public Key Cryptography Standard #8 v1.2, Private-Key Information Syntax Standard, http://www.rsa.com/pub/pkcs/ascii/pkcs-8.asc. [PKIX] Internet Public Key Infrastructure X.509 Certificate and CRL Profile Internet Draft, IETF PKIX Working Group, March 25, 1998, ftp://ds.internic.net/internet- drafts/draft-ietf-pkix-ipki-part1-07.txt. [SMIME2] S/MIME Version 2 Message Specification, RFC 2311, http://www.imc.org/smime-pgpmime.html. [SMIME3] S/MIME Version 3 Message Specification, Internet Draft, March 24, 1998, ftp://ds.internic.net/internet-drafts/draft-ietf-smime-msg-03.txt. [SMIMEC] S/MIME Version 3 Certificate Handling, Internet Draft, March 24, 1998, ftp://ds.internet.net/internet-drafts/draft-ietf-smime-cert-03.txt 3. Definition of Terms Crypto Token: External (to the SFL) software and/or hardware used to implement a set of crypto algorithms. The Fortezza Card is an example of a crypto token. The crypto software modules contained within the BSAFE and Crypto++ libraries are also examples of crypto tokens. Crypto Token Library: External (to the SFL) library used by the SFL to access the crypto algorithms and related security services provided by a crypto token. The Fortezza Cryptologic Interface (CI) Library, BSAFE and Crypto++ are examples of crypto token libraries. Crypto Token Interface (CTI) Library: Internal SFL library that provides abstracted crypto services using one or more crypto token libraries. For example, there is a SFL Fortezza CTI Library that calls the Fortezza CI Library to access the DSA, KEA, and Skipjack algorithms. There is a SFL Crypto++ CTI Library that calls the Crypto++ library to access the DSA, DES, D-H and SHA1 algorithms. There is a SFL BSAFE CTI Library that calls the BSAFE library to access the MD5, MD2, RSA, and RC2 algorithms. 4. Application-SFL Interaction Concepts 4.1. SFL Responsibilities: 1) Uses underlying external crypto token libraries to provide security services such as signing, verifying, encrypting and decrypting. 2) Builds and processes (including ASN.1 encoding and decoding) CMS/ESS objects (SignedData, EnvelopedData, Receipt) including optional security enhancements (eSSSecurityLabels, receiptRequests, algorithm independence, ML Expansion History). It can build and process SignedData objects that contains only X.509 Certificates and/or Certificate Revocation Lists (CRL) (i.e. no content). It can build and process SignedData objects that include multiple SignerInfos (i.e. multiple signatures on the content). It supports the CMS external signature requirement (i.e. generates/verifies SignedData in which the content is separate from the SignedData). 3) Protects data independent of the encapsulated content format. Any type of data can be protected. It protects data as a binary blob of data. It does not parse data to be protected. For example, it does not build or parse a MIME header. As another example, it does not ASN.1 encode or decode X.400 messages. 4) Supports Mail List Agent (MLA) processing. 5) Implements the following attributes defined in [CMS], [ESS] and [SMIME3]: ReceiptRequest, ESSSecurityLabel, MLExpansionHistory, ContentHints, ContentIdentifier, ContentType, MessageDigest, SigningTime, SMIMECapabilities and countersignatures. 4.2. Application Responsibilities: 1) Obtain all required X.509 Certificates, CRLs and Attribute Certificates (AC) from incoming messages, local database, X.500 Directory or other location. 2) Perform all interactions with the user. 3) Validate X.509 Certification paths. The application can use the freeware Certificate Management (CM) Library described in [CMAPI] to decode X.509 Certificates and CRLs, and to validate X.509 Certification Paths. 4) Optionally maintain local database of X.509 Certificates, CRLs and ACs, etc. 5) Build and parse native format (i.e. build/parse MIME headers that encapsulate CMS objects, ASN.1 encode/decode X.400 messages that encapsulate CMS objects, etc). 6) Initialize and manage crypto token library(s) and crypto token(s). 7) Generates new key material, if user-generated key material is required. 8) Use SFL to build and process CMS/ESS objects. Appendix A provides general high- level descriptions of some examples of how an S/MIME application can use the SFL. 5. SFL C API The initial release of the SFL provides a C++ API to the application, but is planned that a later release will also provide a C API. The C API will be a wrapping of the C++ Objects/Methods in C API functions. This will extend the usefulness of the SFL because it will be able to support applications that can call upon C and/or C++ functions. This version of the API document includes a brief description of the C API High-Level Functions. A later version of the API document will include a full description of the C API including data structures, function parameters, etc. 1. SM_Decrypt: ASN.1 decodes and decrypts the EnvelopedData object provided by the application. It provides the decrypted content. 2. SM_Encrypt: Encrypts the content provided by the Application and provides the ASN.1 encoded EnvelopedData object. 3. SM_PreProc: ASN.1 decodes a CMS object and provides the information from the decoded object such as the attributes, X.509 Certificates, CRLs, ACs, content (if not encrypted), and other outputs. 4. SM_Sign: Signs content and optional attributes provided by the Application. It provides the ASN.1 encoded SignedData object. It can be used to calculate multiple signatures (i.e. multiple SignerInfos) of the data using various algorithms. It can also be used to add a SignerInfo to an existing SignedData object. It can also be used to generate a SignedData object in which the content is absent to support the CMS external signature requirement. 5. SM_ValReceipt: ASN.1 decodes and verifies a SignedData object which encapsulates a Receipt content (SignedData/Receipt). If multiple signatures have been applied to the SignedData/Receipt, then the Application can select which signatures are to be verified. It provides the attributes and other outputs. 6. SM_Verify: ASN.1 decodes and verifies a SignedData object. If multiple signatures have been applied to the SignedData object, then the Application can select which signatures are to be verified. It provides the content, attributes and other outputs. If a SignedData/Receipt is requested by the signer and the Application has indicated that a SignedData/Receipt should be built (if requested), then SM_Verify generates it. SM_Verify supports the CMS external signature requirement by allowing the application to pass the content in separately from the SignedData object. 6. SFL C++ API 6.1 C++ Introduction 6.1.1 C++ General Software Conventions 6.1.1.1 Parameters. When appropriate, ASN.1 encoded objects are exchanged between the application and SFL to minimize the dependence of the application on SFL-unique objects. ASCII strings are used to represent Distinguished Names (DN) and Object Identifiers (OID). This strategy facilitates the display of DNs and OIDs. 6.1.1.2 Memory Allocation. The application should instantiate the classes that it needs to use. Deleting or allowing a locally instantiated object to fall out of scope will clean up all memory used by that class and whatever that class contains. If a class or class member’s return value has special memory considerations, they will be described in that class’ description. The next release of the SFL will probably include some class member modifications to handle construction, destruction, and access to an object’s memory in a way that is consistent throughout the entire SFL. These changes will affect the API. 6.1.1.3 Character Strings. All character strings must be terminated by a NULL character. If parameters are not used for a specific function call, then they must be set to values that cannot be misinterpreted as valid. Ideally, the application will use the appropriate class member and will not have to pass parameters as NULL. 6.1.1.4 Exchanging X.509 Objects. The SFL uses the SNACC ASN.1 Library to decode all required X.509 objects including Certificates, CRLs and ACs. When a CMS/ESS object is decoded, the SFL uses the SNACC Library to decode the components that it recognizes, but it does not decode the ANY fields that it does not recognize. If needed for internal use, the SFL decodes the X.509 objects using the appropriate SNACC decoders. If an X.509 object that was included in the CMS object needs to be returned to the application, the SFL will re- encode that object. The application must provide all X.509 Certificates, CRLs and ACs to the SFL as ASN.1 DER encoded objects. The SFL decodes the X.509 Certificates, ACs and CRLs for internal use as described above. If the application provides a X.509 Certificate, CRL or AC that the SFL can't decode, then it returns an error. If the application has provided valid ASN.1 encoded objects, then the SFL includes the ASN.1 encoded X.509 objects in the CMS object exactly as they were provided by the application. 6.1.1.5 Other Issues. The CSM_TokenInterface and CSM_BaseTokenInterface classes are not discussed in this document because the application will not directly use these classes. See the SFL Maintenance document and the CTI API document for more information. 6.1.1.6 Encapsulation of SFL Objects. As required by [CMS], every CMS object must be encapsulated in a ContentInfo SEQUENCE. Therefore, every CMS object produced by the SFL is encapsulated in a ContentInfo SEQUENCE. Similarly, every CMS object that is provided to a SFL function must be encapsulated within a ContentInfo SEQUENCE. The SFL can be used to determine the content type of the CMS object indicated by the ContentInfo contentType OID. It can also be used to determine the content type of the data encapsulated by the CMS object (encapsulated content type). 6.1.2. SFL C++ Classes Introduction The SFL is designed in a modular architecture using object-oriented techniques. The application interacts with the SFL through the SFL API using a hierarchy of C++ classes. The High-Level classes contain CMS/ESS objects and functions necessary for Sign, Verify, Encrypt, Decrypt, and ASN.1 encoding/decoding operations. The High Level classes isolate the application from the SNACC C++ classes used within the SFL. The High Level classes are broken down further into sub-types known as the Low Level classes. The application can directly access the Low Level classes. The Low Level classes contain SNACC C++ classes. The CSM_CSInst class represents a Crypto Service Instance. The CSM_CSInst provides a way for the application to select and work with the crypto services that it wants to use. Each CSM_CSInst class includes information related to the use of an X.509 Certificate and associated private key within a crypto token library. If the application can choose from a variety of private keys, then the application maintains a list of CSM_CSInst classes. For example, there will be a CSM_CSInst class for each slot that contains a private key on the Fortezza crypto token. The list of CSM_CSInst classes is given to the SFL (in the CSMIME class) so that the SFL can use them to access the crypto services that the application wants to use. Each CSM_CSInst refers to a set of algorithms including content encryption, message digest, DS and KM. Note that there may be CSM_CSInst classes that do not have private keys. For example, there may be a CSM_CSInst created for a DS algorithm provided by a crypto token library that can only be used to verify signatures, so it will not include a private key. The CSMIME class represents the SFL Library. It has the two primary purposes of containing the error information and containing the list of CSM_CSInst classes. It has members to operate on this information. The CSMIME class should be constructed and initialized whenever an application that uses the SFL starts. Figure 1 is an abstract illustration of the instance class hierarchy. CSMIME includes a list of CSM_CSInst classes. Each CSM_CSInst includes a CTI class (cast as a CSM_TokenInterface). Each CTI class is derived from either another CTI class or CSM_BaseTokenInterface that is derived from CSM_TokenInterface. Thus, the CSMIME class contains the list of instances that can be used. Each instance contains an abstract interface to the cryptographic services provided by the CTI class. Figure 2 illustrates a basic hierarchy for the message classes. This figure does not include the entire hierarchy. The low-level SNACC classes and the low-level SFL classes are excluded from the figure for simplicity. The figure has four features of interest. Down the left side of the figure are the “high-level message classes” named with the CSM_*Msg convention. In the center of the figure are the “low-level message classes” named with the CSM_*Data convention. The SNACC classes SignedData and EnvelopedData are shown on the right side of the figure. The remaining classes (contained in dashed boxes) are SFL “low-level component classes.” 6.2 The High Level Message Classes The application should use the high level message classes (CSM_ContentInfoMsg, CSM_SignMsg, CSM_VerifyMsg, CSM_EncryptMsg, and CSM_DecryptMsg) to handle the different types of CMS data (respectively, ContentInfo with unknown encapsulated content, creating a ContentInfo with a SignedData, receiving a ContentInfo with a SignedData, creating a ContentInfo with an EnvelopedData, and receiving a ContentInfo with an EnvelopedData). Each class description includes constructors, “attribute” members, and “operational” members. The class description introduction describes what classes it derives from. The “attribute” members are functions that act on the data in the class (typically, gets and sets). Public member variables are also mentioned in the attribute section. “Operational” members are functions that use the data in the class to do some type of processing (such as signing or encrypting). Every class that the application might use is described in this section. Some of these classes are derived from other classes. To fully understand the class, the entire class hierarchy must be studied. 6.2.1 CSM_SignMsg The CSM_SignMsg class represents a CMS SignedData object. The application can use this class to originate signed messages. CSM_SignMsg is derived from CSM_SignData and CSM_CommonData. Typically, the application will create this class, put data into it as appropriate using the class attribute members, and then generate the resulting ContentInfo/SignedData using the Sign operational member in conjunction with the CSMIME/CSM_CSInst classes. 6.2.1.1 CSM_SignMsg Construction Members CSM_SignMsg::CSM_SignMsg(); CSM_SignMsg::CSM_SignMsg(CSM_Buffer *pContent); CSM_SignMsg::CSM_SignMsg(CSM_Content *pMsgContent); The application can use the default constructor or one of the alternate constructors. The first alternate allows the application to construct with the content coming from a CSM_Buffer. The second alternate allows the application to construct with the content coming from a CSM_Content. 6.2.1.2 CSM_SignMsg Attribute Members void CSM_SignMsg::SetIncludeOrigCertsFlag(bool bFlag); The application should use the SetIncludeOrigCertsFlag member to indicate that CSM_SignMsg::Sign should include originator certs in the produced SignedData. If there is a user certificate in the CSM_CSInst, then that user cert will be included if this flag is set. If there is a user cert path in the CSM_CSInst, then that user cert path will be included if this flag is set. Default value is true. void CSM_SignMsg::SetIncludeContentFlag(bool bFlag); The application should use the SetIncludeContentFlag member to indicate if CSM_SignMsg::Sign should include the content in the produced SignedData. If the application wants to generate an external signature, then it should not include the content. Default value is true. This class includes the following public pointers: ? CSM_MsgAttributes *m_pCSMAuthAttributes: the application places attributes that need to be authenticated into this member. ? CSM_MsgAttributes *m_pCSMUnauthAttributes: the application places attributes that do not need to be authenticated into this member. (See the section describing the CSM_MsgAttributes class for details) ? CSM_MsgCertCrls *m_pCSMMsgCertCrls: the application places certs and CRLs in this class that it wants to have included in the SignedData certificates and crls components. 6.2.1.3 CSM_SignMsg::Sign SM_RET_VAL CSM_SignMsg::Sign(CSMIME *pCSMIME); Signs content and optional attributes provided by the application. It generates an ASN.1 encoded CMS SignedData object encapsulated in an ASN.1 encoded ContentInfo SEQUENCE. The application must provide initialized and logged-in CSM_CSInsts for Sign’s use. The application provides the data to be signed (via the constructor or SetEncapContent), authenticated attributes, and unauthenticated attributes (via the appropriate CSM_SignMsg members). The application also can provide X.509 Certificates, CRLs and ACs to be included in the SignedData object (via m_pCSMMsgCertCrls and SetIncludeCerts). Prior to using CSM_SignMsg::Sign, the application must determine which DS algorithm(s) (and accompanying hashing algorithm(s)) and which signer’s DS private key(s) are to be used to generate the signature(s). Each CSM_CSInst class (contained in the CSMIME parameter) indicates one set of DS private key material and one DS algorithm. Prior to calling CSM_SignMsg::Sign, the application must ensure that at least one CSM_CSInst which points to a DS private key is marked for use with the “UseThis” flag (unless it wants to create a "certs-only" SignedData which is not signed). Sign will use each CSM_CSInst that includes a pointer to a private DS key and that is marked with "UseThis" to sign the object (i.e. create a signerInfo for each designated CSM_CSInst that includes the signature of the SignedData content and authenticatedAttributes, if any). There are at least two different ways that the application can cause the appropriate CSM_CSInst(s) to be marked: 1) The application can determine which CSM_CSInst (i.e. private key) that the user wants to use to sign the data and then it can call the CSM_CSInst:UseThis member function to mark the selected CSM_CSInst by setting the "UseThis" flag. 2) The application can call the CSMIME::UseAllSigners function to help it determine which CSM_CSInst(s) to mark. In this case, CSMIME::UseAllSigners will traverse the CSM_CSInsts and mark the ones that point to a DS private key with "UseThis". If the application also provides one or more certificates, then CSMIME::UseAllSigners will mark each CSM_CSInst that points to a DS private key and that include a DS algorithm identifier that matches that in the certificates. This is useful to match the signing algorithm for the data with the capabilities of the recipients. CSMIME::UseAllSigners may mark multiple CSM_CSInsts with the “UseThis” flag. This will cause CSM_SignMsg::Sign to generate multiple signatures (i.e. SignerInfos) for the SignedData. The application must ensure that the appropriate CSM_CSInsts are marked with “UseThis” prior to calling Sign. If a CSM_CSInst is marked with “UseThis” that the application does not wish to be used to sign the data, then the application calls CSM_CSInst::DontUseThis to unset the “UseThis” flag. This strategy ensures that it is absolutely clear which private DS key(s) that Sign will use to sign the SignedData. This enables the application to unambiguously communicate to the user which private key will be used prior to calling Sign. If no CSM_CSInsts are marked with "UseThis" that point to a DS private key and the application provides a content to be signed, then Sign returns an error. Note that if the application did not provide a content to be signed, then it is valid that no CSM_CSInsts are marked. In that case, no signerInfos will be constructed which is valid for a "certs-only" SignedData described in [SMIME3]. When the following text mentions the “designated CSM_CSInst”, then that is an instance (in the CSM_CSInst list) that has been marked with “UseThis”. For each designated CSM_CSInst, Sign digests the data to be signed using the digest algorithm marked as "preferred" by the designated CSM_CSInst. If authenticated attributes were provided, then Sign includes them in the digest calculation. Sign generates the signature value using the DS algorithm and signer’s DS private key material indicated by the designated CSM_CSInst. Sign produces the ASN.1 encoded ContentInfo SEQUENCE encapsulating the ASN.1 encoded SignedData object that the application can retrieve using the GetEncodedBlob. If the application uses SetIncludeOrigCertsFlag(true), then Sign includes the signer’s ASN.1 DER encoded X.509 Certificate(s) and ACs included in the designated CSM_CSInst in the ASN.1 encoded SignedData. At a minimum, the signer’s ASN.1 DER encoded DS X.509 Certificate should be included in the CSM_CSInst. If the application requires that the signer’s complete X.509 Certification path must be included, then the application should ensure that all of the ASN.1 DER encoded X.509 Certificates composing the signer’s X.509 Certification path are stored in the designated CSM_CSInst. If the application requires that X.509 Certificates in addition to (or instead of) the signer’s X.509 Certification path must be included, then the application must include those ASN.1 DER encoded X.509 Certificates in the m_pCSMMsgCertCrls member. Likewise, if the application requires that CRLs must be included, then the application must include those ASN.1 DER encoded CRLs in the m_pCSMMsgCertCrls member. Sign can be used to calculate multiple signatures (i.e. multiple SignerInfos) of the data using different algorithms and different sets of the originator’s private DS key material. For example, if the originator needs to send a message that is signed using both DSA and RSA, then the application can cause Sign to build a SignedData object including a SignerInfo containing a DSA signature and another SignerInfo containing a RSA signature. If the application requires multiple signatures, then it must mark each CSM_CSInst to be used to sign the data (see the CSM_CSInst section for more details). For each application-designated CSM_CSInst, Sign generates a SignerInfo including the signature value using the DS algorithm and signer’s DS private key material indicated by the application- designated CSM_CSInst. For each application-designated CSM_CSInst, Sign includes the signer’s ASN.1 DER encoded X.509 Certificate(s) and ACs from the CSM_CSInst in the resulting ASN.1 encoded SignedData if the application used SetIncludeOrigCertsFlag(true). Sign includes attributes in each SignerInfo as specified in the CSMSignMsg::m_pAuthAttributes and m_pUnauthAttributes members. Sign provides the ASN.1 encoded ContentInfo SEQUENCE encapsulating the new ASN.1 encoded SignedData object including the multiple signatures. The application may provide authenticated and/or unauthenticated attributes to Sign using the m_pAuthAttributes and m_pUnauthAttributes members of CSM_SignMsg. By default, these attributes will be included in every generated SignerInfo. If the application wishes an attribute to be included only in a specific SignerInfo, it should mark the attribute with the InstanceID of the CSM_CSInst that will sign the SignerInfo. Refer to the description of CSM_MsgAttributes for more information. [ESS] states that there can be multiple SignerInfos within a SignedData object each of which include a receiptRequest, ESSSecurityLabel and/or MLExpansionHistory attribute. [ESS] also states that all of these attributes of the same type present in a SignedData object MUST BE identical (i.e. all ESSSecurityLabels must be identical, etc). If multiple eSSSecurityLabel, MLExpansionHistory or receiptRequest attributes are provided by the application through the m_pAuthAttributes and m_pUnauthAttributes members, then Sign ensures that all attributes of the same type are identical. Regarding the “external signatures” requirements documented in [CMS]: Sign can produce a SignedData object in which the content is absent. If the application calls CSM_SignMsg::SetIncludeContentFlag(false) then the content will be excluded from the SignedData. Note that the content must still be provided in CSM_SignMsg even if SetIncludeContentFlag is false because Sign needs to digest it to calculate the digital signatures. Figure 3 illustrates a sample signing operation with the SFL. The dashed boxes indicate steps in the process, the boxes inside the dashed boxes indicate classes used in that step, the arrows into the dashed boxes indicate net input to a step and the arrows out of the dashed boxes indicate net output of a step. 6.2.2 CSM_VerifyMsg The CSM_VerifyMsg class represents a CMS SignedData object. The application can use this class to process received signed messages. CSM_VerifyMsg is derived from CSM_VerifyData and CSM_CommonData. Typically, the application will create this class and put the incoming ASN.1 encoded ContentInfo/SignedData into it using either the constructor or SetEncodedBlob. Then the application will manipulate it and provide other signature verification inputs as necessary using the other class attribute members, and then verify the signatures using the Verify operational member in conjunction with the CSMIME/CSM_CSInst classes. 6.2.2.1 CSM_VerifyMsg Construction Members CSM_VerifyMsg::CSM_VerifyMsg(); CSM_VerifyMsg::CSM_VerifyMsg(CSM_Buffer *pBlob); CSM_VerifyMsg::CSM_VerifyMsg(CSMIME *pCSMIME, CSM_Buffer *pBlob); CSM_VerifyMsg::CSM_VerifyMsg(CSM_ContentInfoMsg *pCI); CSM_VerifyMsg::CSM_VerifyMsg(CSM_Content *pContent); The application can use the default constructor or one of the alternate constructors. The first alternate allows the application to construct with the content coming from a CSM_Buffer. The second alternate allows the same type of construction but also accepts CSMIME as input. With the second alternate, the constructor is able to compare the Algorithm OIDs used in the message with the Algorithm OIDs supported by the available instances and then make matches as to which instances can process the message. For more information, see below. The third and fourth alternate allow the application to construct the CSM_VerifyMsg from either a CSM_ContentInfoMsg or from a CSM_Content. 6.2.2.2 CSM_VerifyMsg Attribute Members This class includes public pointers to the following classes that the application may use: ? CSM_MsgSignerInfos *m_pSignerInfos: the application can use this member to access the SignerInfos in the SignedData. See the description of CSM_MsgSignerInfos for more information. ? CSM_MsgCertCrls *m_pMsgCertCrls: The application can use this member to provide the validated certificates of the SignerInfos that it wishes to verify. For example, if a SignedData includes SignerInfo1, SignerInfo2, and SignerInfo3, and the application only wanted to verify the signature in SignerInfo1, then the application should place the validated cert(s) for the signer of SignerInfo1 in m_pMsgCertCrls. 6.2.2.3 CSM_VerifyMsg::Verify SM_RET_VAL CSM_VerifyMsg::Verify(CSMIME *pCSMIME); SM_RET_VAL CSM_VerifyMsg::Verify(CSMIME *pCSMIME, CSM_Buffer *pBlob); The ASN.1 encoded SignedData can be passed into Verify as a parameter (as in the second Verify) or can be set through the constructor or the PreProc members. If the application does not pass the ASN.1 encoded SignedData to Verify, then the incoming ASN.1 encoded ContentInfo containing a SignedData must have already been ASN.1 decoded by either the CSM_VerifyMsg constructor (if a constructor was used with the content as a parameter) or by the application specifically calling the CSM_VerifyMsg::PreProc member. This member verifies an ASN.1 encoded SignedData object. If multiple signatures have been applied to the SignedData, then the application can select which signatures are to be verified. Verify produces the content, SignerInfos containing authenticatedAttributes and unauthenticatedAttributes, and other outputs. If a SignedData/Receipt is requested by the signer, the application can retrieve the SignedData/Receipt using the GetSignedReceipt member. The application must initialize the cryptographic token and must login prior to calling Verify. The ASN.1 encoded ContentInfo containing an ASN.1 encoded SignedData must be “pre-processed” prior to using the CSM_VerifyMsg::Verify member. This “pre-processing” will be done by either specifically calling CSM_VerifyMsg::PreProc or by using the constructor with content. “Pre- processing” makes information from the decoded SignedData object available including X.509 Certificates, CRLs, and ACs in the object. “Pre-Processing” provides the SignerInfos information from the decoded SignedData object in the m_pSignerInfos member (see the CSM_MsgSignerInfos class for a detailed description of this class’ use). If multiple signatures have been applied to the SignedData, then the application should prompt the user (or otherwise determine) which of the SignerInfos need to be verified. The application uses the Issuer name and serialNumber from each SignerInfo to identify the X.509 Certificate of the entity that produced the signature value contained in the SignerInfo. For each signature that the application requires to be verified, the application must obtain and validate the signer’s X.509 Certification path. The application can use the CM Library CM_RetrieveKey function to validate each signer’s X.509 Certification Path. For each signature that the application requires to be verified, the application must provide the validated and ASN.1 encoded cert path in the CSM_VerifyData::m_pMsgCertCrls member. The application provides the SignedData object for verification either through the CSM_VerifyMsg constructor or with the SetEncodedBlob members. The application must provide the ASN.1 encoded SignedData encapsulated within an ASN.1 encoded ContentInfo. Every CMS object that is provided by a SFL function is encapsulated within a ContentInfo SEQUENCE. Therefore, if an SFL function provided the SignedData that requires verification, then the application can simply pass in the SignedData as it was provided by the SFL function. If the application provides a SignedData object that is not encapsulated by a ContentInfo SEQUENCE or if the ContentInfo->contentType OID does not match the SignedData OID, CSM_VerifyMsg::Verify returns an error. For each SignerInfo from the decoded SignedData object, CSM_VerifyMsg::Verify attempts to match the IssuerAndSerialNumber with one of the structures in the CSM_VerifyData::m_pMsgCertCrls. If a match is found, then Verify attempts to verify the signature value contained in the SignerInfo using the public key from the ASN.1 encoded certificate (or Certification Path in the case of a DSA signature verification) in the matching m_pMsgCertCrls member. This signature verification is performed using the DS algorithm specified in the SignerInfo being verified. If the signature is successfully verified, then Verify marks the SignerInfo as verified in the m_pSignerInfos member. The application can use the m_pSignerInfos list to determine exactly which signatures were verified by Verify. If a SignedData/Receipt is requested by the signer, the application can retrieve it using the CSM_VerifySignature::GetSignedReceipt member. This strategy allows the application to retrieve the SignedData/Receipt when it wants it instead of with every Verify. The application may not want to construct a SignedData/Receipt after subsequent re-verifications of the SignedData object. The application indicates that a SignedData/Receipt should be built by calling GetSignedReceipt (after calling Verify). If one (or more) of the SignerInfos for which the signature was verified includes a receiptRequest attribute requesting that the recipient return a SignedData/Receipt, then GetSignedReceipt constructs the SignedData/Receipt encapsulated in an ASN.1 encoded ContentInfo SEQUENCE. If the receiptRequest attribute requested SignedData/Receipts from a ReceiptList, then GetSignedReceipt uses the recipient’s private DS key material and DS algorithm indicated by the CSM_CSInst corresponding to the matched GeneralName in the ReceiptList to sign the SignedData/Receipt. If the receiptRequest attribute did not include ReceiptList, then GetSignedReceipt uses the recipient’s private DS key material and DS algorithm indicated by the designated CSM_CSInst to sign the SignedData/Receipt. Therefore, prior to calling Verify, the application may mark instances indicating the DS private key material to be used to sign the SignedData/Receipt (see description of CSM_CSInst for more information, also, see the “default” CSM_CSInst description in CSM_SignMsg::Sign). If the application does not mark a CSM_CSInst and the receiptRequest attribute did not include ReceiptList, then GetSignedReceipt selects a CSM_CSInst including the DS algorithm that matches the one used to sign the SignerInfo containing the receiptRequest attribute. If GetSignedReceipt builds a SignedData/Receipt, it always populates SignedData->certificates with the recipient’s X.509 Certificates and ACs included in the CSM_CSInst which was used to sign the receipt. At a minimum, the recipient’s ASN.1 DER encoded DS X.509 Certificate should be included in the CSM_CSInst. If the application requires that issuer X.509 Certificates must be included in the recipient’s X.509 Certification path in SignedData->certificates, then the application must include those issuer ASN.1 DER encoded X.509 Certificates in the application-designated CSM_CSInst. The initial SFL GetSignedReceipt function does not provide the capability to include CRLs in the SignedData encapsulating the Receipt. If the application uses GetSignedReceipt to build a SignedData/Receipt object, then the application must follow the rules stated in [ESS] to determine to whom the SignedData/Receipt must be sent. Verify provides all of the information (such as the MLExpansionHistory and receiptRequest attributes, if present) that the application needs to make that determination. This information is included through the CSM_VerifyMsg::m_pSignerInfos member. [ESS] states that there can be multiple SignerInfos within a SignedData object each of which include a receiptRequest attribute. [ESS] also states that all receiptRequest attributes present in a SignedData object MUST BE identical. Furthermore, all user agents MUST support the DSA algorithm. Therefore, a recipient never needs to build multiple SignedData/Receipts for a SignedData object. For example, if the SignedData object includes both RSA-signed and DSA-signed SignerInfos that both include receiptRequest attributes and the recipient uses CSM_VerifyMsg::Verify to verify both SignerInfos, then CSM_VerifyMsg::GetSignedReceipt only needs to build a single DSA-signed SignedData/Receipt. This is true because an RSA-signed SignedData/Receipt is not required because the originator must be able to accept a DSA-signed SignedData/Receipt. CSM_VerifyMsg::GetSignedReceipt examines the authenticatedAttributes field of each of the SignerInfos for which it verifies a signature in the SignedData object to determine if all receiptRequest attributes are identical. If they are not identical, then it returns an error. [ESS] states that there can be multiple SignerInfos within a SignedData object each of which include a eSSSecurityLabel attribute. [ESS] also states that all eSSSecurityLabel attributes present in a SignedData object MUST BE identical. The application should only process a eSSSecurityLabel attribute if the signature of the SignerInfo which covers the eSSSecurityLabel attribute can be verified. CSM_VerifyMsg::Verify examines the authenticatedAttributes field of each of the SignerInfos for which it verifies a signature in the SignedData object to determine if all ESSSecurityLabel attributes are identical. If they are not identical, then it returns an error. CSM_VerifyMsg::Verify should be able to process the content separate from the SignedData (in addition to the normal SignedData which includes the content). In order to facilitate this “external signature” feature, the application would go about verifying a SignedData as normal. However, prior to calling Verify, the application should load the external content into the CSM_CommonData (CSM_VerifyMsg is derived from CSM_CommonData). When Verify sees that the content is not present in the ASN.1 decoded SignedData, it will use the content from the CSM_CommonData for signature verification. If Verify finds no content in the ASN.1 decoded SignedData and none is available in the CSM_CommonData, then Verify returns an error. [ESS] states that there can be multiple SignerInfos within a SignedData object each of which include a MLExpansionHistory attribute. [ESS] also states that all MLExpansionHistory attributes present in a SignedData object MUST BE identical. The application should only process a MLExpansionHistory attribute if the signature of the SignerInfo which covers the attribute can be verified. CSM_VerifyMsg::Verify examines the authenticatedAttributes field of each of the SignerInfos for which it verifies a signature in the SignedData object to determine if all MLExpansionHistory attributes are identical. If they are not identical, then it returns an error. Figure 4 illustrates a sample signature verification operation with the SFL. The dashed boxes indicate steps in the process, the boxes inside the dashed boxes indicate classes used in that step, the arrows into the dashed boxes indicate net input to a step and the arrows out of the dashed boxes indicate net output of a step. 6.2.2.4 CSM_VerifyMsg::PreProc SM_RET_VAL CSM_VerifyMsg::PreProc(CSMIME *pCSMIME); SM_RET_VAL CSM_VerifyMsg::PreProc(CSMIME *pCSMIME, CSM_Buffer *pBlob); ASN.1 decodes a CMS object and provides decoded information such as the authenticatedAttributes, unauthenticatedAttributes, X.509 Certificates, CRLs, ACs, content, and other outputs. The application only needs to use this member if it did not use a constructor with content when CSM_VerifyMsg was created. The constructors with content call PreProc automatically. The application does not need to initialize the cryptographic token or login prior to constructing a CSM_VerifyMsg with content or calling PreProc, because “pre-processing” does not require any cryptographic services. It does not validate any signatures. It may be called as part of the message receiving process. It may also be called to extract the unencrypted encapsulated content from a stored ASN.1-encoded SignedData object. The application provides the ASN.1 encoded CMS object to be decoded. It does this using a constructor with content or by using the SetEncodedBlob member. The provided ASN.1 encoded CMS object must be encapsulated within an ASN.1 encoded ContentInfo. Every CMS object that is provided by a SFL function is encapsulated within a ContentInfo SEQUENCE. Therefore, if an SFL function provided the CMS object that requires decoding, then the application can simply pass in the CMS object as it was provided by the SFL function. If the application provides a CMS object that is not encapsulated by a ContentInfo SEQUENCE, then PreProc returns an error. PreProc makes all X.509 Certificates, CRLs and ACs extracted from the CMS data object as ASN.1 encoded objects available via the CSM_VerifyMsg::m_pSignerInfos member (see the CSM_SignerInfos description for detailed information). PreProc marks (with m_Applicable) all of the CSM_CSInsts in the pCSMIME class that could potentially be used to verify the signatures in the message. The subsequent call to CSM_VerifyMsg::Verify can then be greatly simplified since the application can choose to not do any other “processing” on the instances list. Alternately, the application can traverse the CSM_CSInsts list, and mark or unmark whatever instances it wants used (or not used). 6.2.2.5 CSM_VerifyMsg::GetSignedReceipt CSM_Buffer* CSM_VerifyMsg::GetSignedReceipt(); The application may use GetSignedReceipt after calling CSM_VerifyMsg::Verify to retrieve the ASN.1 encoded “signed receipt.” This signed receipt is actually an ASN.1 encoded ContentInfo containing an ASN.1 encoded SignedData containing an ASN.1 encoded Receipt that has been signed. It should be sent as directed by the ReceiptRequest attribute. This member will only succeed if there is a ReceiptRequest attribute in the incoming SignedData. For a detailed description of what GetSignedReceipt does, see the description of CSM_VerifyMsg::Verify. 6.2.3 CSM_EncryptMsg The CSM_EncryptMsg class represents an encrypted CMS EnvelopedData object. The application can use this class to originate an encrypted message. CSM_EncryptMsg is derived from CSM_EncryptData and CSM_CommonData. Typically, the application will create this class, put data into it as appropriate using the class attribute members, and then generate the resulting ContentInfo/EnvelopedData using the Encrypt operational member in conjunction with the CSMIME/CSM_CSInst classes. 6.2.3.1 CSM_EncryptMsg Construction Members CSM_EncryptMsg::CSM_EncryptMsg(); CSM_EncryptMsg::CSM_EncryptMsg(CSM_Buffer *pBlob); CSM_EncryptMsg::CSM_EncryptMsg(CSM_Content *pContent); The application can use the default constructor or one of the alternate constructors. The first alternate allows the application to construct with the content coming from a CSM_Buffer. The second alternate allows the application to construct the CSM_EncryptMsg from a CSM_Content object. 6.2.3.2 CSM_EncryptMsg Attribute Members void CSM_EncryptMsg::SetIncludeOrigCertsFlag(bool bFlag); The application should use the SetIncludeOrigCertsFlag member to indicate that CSM_EncryptMsg::Encrypt should include originator certs in the produced EnvelopedData->OriginatorInfo. This only applies if using an appropriate KM algorithm such as KEA or DH. If there is a user certificate in the CSM_CSInst, then that user cert will be included if this flag is set. If there is a user cert path in the CSM_CSInst, then that user cert path will be included if this flag is set. void CSM_EncryptMsg::SetContentEncryptionOID(COID *pContentEncryptionOID); The application should use setContentEncryptionOID to specify which content encryption algorithm will be used to encrypt the content in the EnvelopedData. This class includes public pointers to the following classes that the application may use: ? CSM_RecipientLst *m_pRecipients: the application should provide the validated certificates of the recipients that it wishes to produce RecipientInfos for. ? CSM_MsgCertCrls *m_pMsgCrtCrls: the application can place X.509 certificates, Attribute certificates, and CRLs in this class that it wants included in the produced EnvelopedData->originatorInfo. 6.2.3.3 CSM_EncryptMsg::Encrypt SM_RET_VAL CSM_EncryptMsg::Encrypt(CSMIME *pCSMIME); Encrypts a content provided by the application (via SetEncapContent). It provides the ASN.1 encoded CMS EnvelopedData object encapsulated in an ASN.1 encoded ContentInfo SEQUENCE (via GetEncodedBlob). The application must initialize the cryptographic token and must call login prior to using Encrypt. The application provides the data to be encrypted (via the constructor or SetEncapContent). Prior to using Encrypt, the application must determine the recipients of the envelopedData object. The application must retrieve and validate the KM X.509 Certification Path for each recipient (could use freeware CM Library CM_RetrieveKey function). The application must store the validated recipient certs in m_pRecipList. Prior to using Encrypt, the application must determine which KM and content encryption algorithms are to be used to protect the message. Each CSM_CSInst lists one or more content encryption algorithms and a single KM algorithm. In most cases, the CSM_CSInst also points to a private KM key. The CSM_CSInst classes that will be used for KM Encryption must be marked with “UseThis” prior to using the Encrypt function. The application can determine which CSM_CSInst that it wants to use and then it can call the CSM_Inst::UseThis member function to mark the CSM-CSInst with "UseThis". CSM_Inst::UseThis will return an error if the application attempts to mark multiple CSM_Inst classes that include the same KM algorithm OID. For each identified KM algorithm (including RSA), the application must ensure that at least one CSM_Inst is marked with "UseThis" which points to a CTI library providing the identified KM algorithm. The application provides the content encryption algorithm separately from the list of CSM_CSInsts. This strategy ensures that it is absolutely clear which CSM_CSInsts that Encrypt will use as part of the process to encrypt the EnvelopedData. For KM algorithms in which the originator's private KM key will be used as part of the process to encrypt the MEK for the recipient, then this strategy enables the application to unambiguously communicate to the user which private key will be used prior to calling Encrypt. Encrypt will perform the following steps: 1) Encrypt will traverse the list of CSI_Insts (starting with head of list) and use the first one that includes the application-provided contentEncryption OID to encrypt the content. If the application does not provide the contentEncryption OID or if none of the CSM_CSInsts include the application-provided contentEncryption OID, then Encrypt returns an error. Note: Prior to calling Encrypt, if the application requires that a specific CSM_CSInst must be used to provide the content encryption service, then it must re-order the list of CSM_CSInsts so that the preferred CSM_CSInsts is first. 2) Encrypt will loop through the list of recipient certificates. For each certificate, it will perform the following: a) Encrypt will identify the KM algorithm required to encrypt the MEK for the recipient. b) Encrypt will loop through the CSM_CSInsts to determine the CSM_CSInst that is marked with "UseThis" and that includes the identified KM OID in its list of supported KM algorithms. c) IF Encrypt finds a match, then it will use the private key (if required) and CTI pointed to by the matched CSM_CSInst to encrypt the MEK for the recipient. ELSEIF Encrypt doesn't find a match, then it will return an error. When the following text mentions the “designated CSM_CSInst”, then that is an instance (in the CSM_CSInst list) that has been marked with “UseThis”. RSA: If a KM algorithm is to be used that does not require the originator’s private key material (e.g. RSA), then application must mark the originator CSM_CSInst with the UseThis function. The application passes CSM_CSInsts to Encrypt. Encrypt randomly generates a MEK. It then encrypts the data using the MEK in conjunction with the encryption algorithm indicated by the designated CSM_CSInst. Encrypt uses the KM algorithm indicated by the designated CSM_CSInst to uniquely protect the MEK for each recipient. For each recipient, Encrypt then uses the recipient’s public key material to uniquely protect the MEK for the recipient. Encrypt creates the ASN.1 encoded ContentInfo SEQUENCE encapsulating the ASN.1 encoded EnvelopedData object. This can be retrieved with GetEncodedBlob. KEA/DH: If a KM algorithm is selected that requires the originator’s private key material (e.g. KEA, DH), then the application must select the originator KM private key material to be used as part of the process to uniquely protect the MEK for each recipient. The application must use the CSM_CSInst::UseThis() function to mark the CSM_CSInst that indicates the algorithms and originator’s private key material to be used as part of the process to form the pairwise key to be used to uniquely protect the MEK for each recipient. The application passes CSM_CSInsts to Encrypt. Encrypt randomly generates a MEK. It then encrypts the data using the MEK in conjunction with the encryption algorithm indicated by the designated CSM_CSInst. Encrypt uses the KM algorithm indicated by the designated CSM_CSInst to uniquely protect the MEK for each recipient. For each recipient, Encrypt uses the designated originator’s private key material in conjunction with the recipient’s public key material to generate a pairwise key, which is used to uniquely protect the MEK for the recipient. Encrypt populates OriginatorInfo with the originator’s X.509 Certificates and ACs included in the designated CSM_CSInst if CSM_EncryptMsg::SetIncludeOrigCertsFlag(true) has been used. Whatever certs have been included in the used CSM_CSInst will be included. This may be just the originator’s ASN.1 DER encoded KM X.509 Certificate or the full X.509 cert path. If CSM_EncryptMsg::SetIncludeOrigCertsFlag(true) has not been used, then Encrypt populates each recipientInfo originatorCert field with the information identifying the originator’s certificate.Encrypt provides the ASN.1 encoded ContentInfo SEQUENCE encapsulating the ASN.1 encoded EnvelopedData object via GetEncodedBlob. In both cases, Encrypt includes a copy of the MEK that is protected using the originator’s key material. This ensures that the originator will always be able to decrypt the EnvelopedData object. If the application requires that multiple KM algorithms must be used to protect the MEK for various recipients, then the application may indicate each CSM_CSInst to be used to protect the MEK. Encrypt matches the algorithm indicated in each recipient’s KM X.509 Certificate with the appropriate CSM_CSInst. Note that all selected CSM_CSInsts must indicate the same encryption algorithm. For example, if triple DES is used to encrypt the content, then DH could be used to protect the MEK for the DH recipients and RSA could be used to protect the MEK for RSA recipients. If required by the KM algorithm, Encrypt populates OriginatorInfo with the originator’s X.509 Certificates and ACs included in each of the application-designated CSM_CSInsts used to protect the MEK. The SFL includes the option to create an EnvelopedData in which the MEK is protected using a locally stored key (e.g. Fortezza storage key (Ks)). When an EnvelopedData needs to be protected using a locally stored key, then the application calls Encrypt and does not pass in any recipients. The application designates the CSM_CSInst that indicates the algorithms to be used. Encrypt: generates an MEK; uses the MEK in conjunction with the encryption algorithm indicated by the application-designated CSM_CSInsts to encrypt the content; and then uses the locally stored key (e.g. Ks) in conjunction with the KM algorithm indicated by the application-designated CSM_CSInsts to protect the MEK. Encrypt includes information in the recipientInfos that identifies the EnvelopedData as being protected by a locally stored key. For example, when the Fortezza algorithms are indicated by the application, Encrypt constructs a special 8-octet Key Material Identifier (KMID) including: 0010 as most significant four bits to represent a symmetric key; followed by 0000 as local identifier; and followed by six least significant bytes of the Serial Number. In the Fortezza case, EnvelopedData is constructed with a single recipientInfo with rKeyId set to be the aforementioned KMID and keyEncryptionAlgorithm set to id- fortezzaConfidentialityAlgorithm (with algorithm parameters absent). originatorInfo is omitted from the EnvelopedData object. The initial version of the SFL does not allow CRLs to be included in EnvelopedData objects. Figure 5 illustrates a sample encryption operation with the SFL. The dashed boxes indicate steps in the process, the boxes inside the dashed boxes indicate classes used in that step, the arrows into the dashed boxes indicate net input to a step and the arrows out of the dashed boxes indicate net output of a step. 6.2.4 CSM_DecryptMsg The CSM_DecryptMsg class represents a decrypted CMS EnvelopedData object. The application can use this class to process a received encrypted message. CSM_DecryptMsg is derived from CSM_DecryptData and CSM_CommonData. Typically, the application will create this class and put ASN.1 encoded ContentInfo/EnvelopedData into it. Then the application will manipulate it and provide other decryption inputs as necessary using the other class attribute members. Finally, the application would decrypt the content using the Decrypt operational member in conjunction with the CSMIME/CSM_CSInst classes. 6.2.4.1 CSM_DecryptMsg Construction Members CSM_DecryptMsg::CSM_DecryptMsg(); CSM_DecryptMsg::CSM_DecryptMsg(CSM_Buffer *pBlob); CSM_DecryptMsg::CSM_DecryptMsg(CSM_Buffer *pBlob, CSMIME *pCSMIME); CSM_DecryptMsg::CSM_DecryptMsg(CSM_ContentInfoMsg *pCI); The application can use the default constructor or one of the alternate constructors. The first alternate allows the application to construct with the content coming from a CSM_Buffer. The second alternate allows the same type of construction but also accepts CSMIME as input. With the second alternate, the constructor is able to compare the Algorithm OIDs used in the message with the Algorithm OIDs supported by the available instances and then make matches as to which instances can process the message. For more information, see below. The third alternate allows the application to construct the CSM_DecryptMsg from a CSM_ContentInfoMsg. 6.2.4.2 CSM_DecryptMsg Attribute Members This class includes public pointers to the following classes that the application may use: ? CSM_OriginatorInfo *m_pOriginatorInfo: the application can retrieve information about the originator of the EnvelopedData through this member. See CSM_OriginatorInfo for detailed information. ? CSM_RecipientLst *m_pRecipients: the application can retrieve information about the intended recipients of the EnvelopedData through this member. See CSM_Recipient for detailed information. 6.2.4.3 CSM_DecryptMsg::Decrypt SM_RET_VAL CSM_DecryptMsg::Decrypt(CSMIME *pCSMIME); Construction of this class or explicitly calling PreProc will have ASN.1 decoded the ASN.1 encoded CMS EnvelopedData object. Decrypt will decrypt the EncryptedContent contained in the EnvelopedData. Application must initialize the cryptographic token and must call login prior to calling Decrypt. “pre-processing” must be done prior to using Decrypt. This can be done by using the CSM_DecryptMsg::PreProc member or by constructing the class with the ASN.1 encoded ContentInfo/EnvelopedData. “Pre-processing” provides all of the information from the decoded EnvelopedData object including the X.509 Certificates, CRLs and ACs included in the object. Alternately, the originatorInfo may be absent in which case the recipientInfo originatorCert field will include information identifying the originator’s certificate. The EnvelopedData originatorInfo includes information regarding the originator only if a KM algorithm (e.g. DH, KEA) was used to protect a Message Encryption Key (MEK) which requires that the recipient must use the originator’s public key material as part of the process to decrypt the MEK. In that case, originatorInfo must include the X.509 Certificate containing the originator's KM public key material. OriginatorInfo may include multiple KM X.509 Certificates for the same subject (i.e. originator). “Pre-processing” provides the originator’s X.509 Certificate(s), if present, that are included in the EnvelopedData object via the m_pOriginatorInfo member (see the description of the CSM_OriginatorInfo class for detailed information). If required by the KM algorithm (e.g. KEA, DH), the application must retrieve and validate each of the originator’s X.509 Certification paths, and then provide each set of validated originator’s cert paths via the m_pOriginatorInfo member. The application could use the CM Library CM_RetrieveKey function to validate each of the originator’s X.509 Certification Paths. The application provides the EnvelopedData object for decryption through the constructor or via the SetEncodedBlob attribute member. The EnvelopedData object must be encapsulated within a ContentInfo SEQUENCE. Every CMS object that is provided by a SFL function is encapsulated within a ContentInfo SEQUENCE. Therefore, if an SFL function provided the EnvelopedData that requires decryption, then the application can simply pass in the EnvelopedData as it was provided by the SFL function. If the application provides an EnvelopedData object that is not encapsulated by a ContentInfo SEQUENCE or if the ContentInfo->contentType OID does not match the EnvelopedData OID, then Decrypt returns an error. The ASN.1 encoded ContentInfo/EnvelopedData is ASN.1 decoded via either the constructor or the CSM_DecryptMsg::PreProc member. RSA: Decrypt attempts to match one of the recipientInfos in the EnvelopedData with the recipient’s private key material for the matching encryption algorithm contained in the CSM_CSInst classes. It uses the recipient’s private key material to decrypt the MEK. It then uses the MEK to decrypt the encryptedContent. It will provide the decrypted encapsulated content via the GetEncapContent attribute member. DH or KEA: Decrypt attempts to match one of the recipientInfos in the EnvelopedData with the recipient’s private key material for the matching encryption algorithm contained in the CSM_CSInst classes. It attempts to match one of the application-provided validated certs (in m_pOriginatorInfo) containing the set(s) of originator’s public KM key material with the recipientInfo. It uses the recipient’s private key material in conjunction with the originator’s public key material to generate a pairwise key that is then used to decrypt the MEK. It then uses the MEK to decrypt the encryptedContent. It provides the decrypted encapsulated content via the GetEncapContent attribute member. The SFL includes the option to create an EnvelopedData in which the MEK is protected using a locally stored key (e.g. Fortezza storage key (Ks)). When an EnvelopedData protected by the locally stored key needs to be decrypted, then the application provides the EnvelopedData to Decrypt via the CSM_DecryptMsg constructor or SetEncodedBlob attribute member. Decrypt automatically determines if a locally stored key has been used to protect the EnvelopedData. It takes the appropriate actions to decrypt the EnvelopedData using the locally stored key. For example in the Fortezza environment, if Decrypt detects the first four bits of the recipientInfo rKeyId as 0010 and id- fortezzaConfidentialityAlgorithm in the recipientInfo keyEncryptionAlgorithm, then it uses the local user's Ks to decrypt the encryptedKey and then uses the MEK to decrypt the content. Figure 6 illustrates a sample decryption operation with the SFL. The dashed boxes indicate steps in the process, the boxes inside the dashed boxes indicate classes used in that step, the arrows into the dashed boxes indicate net input to a step and the arrows out of the dashed boxes indicate net output of a step. 6.2.4.4 CSM_DecryptMsg::PreProc SM_RET_VAL CSM_DecryptMsg::PreProc(CSMIME *pCSMIME); SM_RET_VAL CSM_DecryptMsg::PreProc(CSMIME *pCSMIME, CSM_Buffer *pBlob); ASN.1 decodes a CMS object and provides decoded information such as the X.509 Certificates and ACs along with other outputs. The application only needs to use this member if it did not use a constructor with an ASN.1 encoded ContentInfo/EnvelopedData (content) when CSM_DecryptMsg was created. The constructors with content call PreProc automatically. The application does not need to initialize the cryptographic token or login prior to constructing a CSM_DecryptMsg with content or calling PreProc, because “pre-processing” does not require any cryptographic services. It does not decrypt any data or validate any signatures. It may be called as part of the message receiving process. The application provides the ASN.1 encoded CMS object to be decoded. It does this using a constructor with content, by passing the ASN.1 encoded CMS object to the PreProc member that accepts this, or by using the SetEncodedBlob member. The provided ASN.1 encoded CMS object must be encapsulated within an ASN.1 encoded ContentInfo. Every CMS object that is provided by a SFL function is encapsulated within a ContentInfo SEQUENCE. Therefore, if an SFL function provided the CMS object that requires decoding, then the application can simply pass in the CMS object as it was provided by the SFL function. If the application provides a CMS object that is not encapsulated by a ContentInfo SEQUENCE, then PreProc returns an error. PreProc makes all X.509 Certificates and ACs extracted from the CMS data object as ASN.1 encoded objects available via the CSM_DecryptMsg::m_pOriginatorInfo member (see the CSM_OriginatorInfo description for detailed information). PreProc marks (with m_Applicable) all of the CSM_CSInsts in the pCSMIME class that could potentially be used to decrypt the message. The subsequent call to CSM_DecryptMsg::Decrypt can then be greatly simplified since the application can choose to not do any other “processing” on the instances list. Alternately, the application can traverse the CSM_CSInsts list, and mark or unmark whatever instances it wants used (or not used). 6.2.5 CSM_ContentInfoMsg The CSM_ContentInfoMsg class represents an unknown CMS piece of data (either a SignedData or an EnvelopedData). The application can use this class to process a received message. CSM_ContentInfoMsg is derived from CSM_CommonData. Typically, the application will create this class and put ASN.1 encoded ContentInfo into it. Then the application will use the class to determine what is inside the ASN.1 encoded ContentInfo. Then the application can manipulate it and provide other decryption inputs as necessary using the other class attribute members. Finally, the application would decrypt the content using the Decrypt operational member in conjunction with the CSMIME/CSM_CSInst classes. 6.2.5.1 CSM_ContentInfoMsg Construction Members CSM_ContentInfoMsg::CSM_ContentInfoMsg(CSM_Buffer *pBuf); When the application receives an unknown CMS Data blob, it can place this blob in a CSM_Buffer and then create a CSM_ContentInfoMsg from the buffer. Then the application can use the members of the CSM_CommonData class (from which CSM_ContentInfoMsg is derived) to determine what CMS data type is in the blob (see CSM_CommonData). 6.2.5.2 CSM_ContentInfoMsg AttributeMembers bool CSM_ContentInfoMsg::IsSignedData(); bool CSM_ContentInfoMsg::IsEnvelopedData(); bool CSM_ContentInfoMsg::IsData(); The application can determine what CMS object is in an ASN.1 encoded ContentInfo by calling IsSignedData, IsEnvelopedData, or IsData. Then the application can create the appropriate high level object from the CSM_ContentInfoMsg. For example, if the application has a ContentInfo, it can put it into a CSM_ContentInfoMsg and then find out what the encapsulated CMS object is. If it turns out to be a SignedData, then it can create a CSM_VerifyMsg from the CSM_ContentInfoMsg to process the encapsulated SignedData. CSM_Buffer* CSM_ContentInfoMsg::GetEncodedCI(); void CSM_ContentInfoMsg::SetEncodedCI(CSM_Buffer &buffer); The application can put the ASN.1 encoded ContentInfo into this class using SetEncodedCI and can retrieve it using GetEncodedCI. 6.2.6 CSM_AddSignMsg The application uses this class in a similar manner as the CSM_SignMsg class except this class has the capability and methods present to add a signature to a CMS SignedData. This class will be fully described in future releases of this document. 6.2.7 CSM_VerifyReceiptMsg If the application receives a ContentInfo/SignedData/Receipt (signed receipt) then it should use the CSM_VerifyReceiptMsg class to verify the signature on the receipt. When the application receives the ContentInfo containing an unknown CMS piece of data, it uses the CSM_ContentInfoMsg class to find out what is in the ContentInfo. If the app learns that the ContentInfo contains a SignedData that contains a Receipt, then it should construct a CSM_VerifyReceiptMsg with the CSM_ContentInfoMsg. It should load the original message (that requested the signed receipt) into the CSM_VerifyReceiptMsg. Then it should use the class the verify the signature in the same manner that it would verify a normal signature (described in the section on CSM_VerifyMsg). 6.2.7.1 CSM_VerifyReceiptMsg Construction Members TBD 6.2.7.2 CSM_VerifyReceiptMsg Attribute Members void SetOriginalMessage(CSM_Buffer *pOrigMsg); The application should use SetOriginalMessage prior to calling Verify to store the original message in the CSM_VerifyReceiptMsg class. The original message that requested the signed receipt is required for verifying the signature on the receipt. 6.3 The Low Level Message Classes 6.3.1 CSM_SignData The CSM_SignData class provides a very low-level method for the application to generate a ContentInfo/SignedData. The class provides public access to the SignedData m_snaccSignedData member which is the SNACC generated class representing the ASN.1 SignedData type. The application can directly fill in the m_snaccSignedData as desired. 6.3.1.1 CSM_SignData::Sign SM_RET_VAL CSM_SignData::Sign(CSMIME *pCSMIME, CSM_MsgCertCrls *pMsgCertCrls, CSM_Buffer *pEncodedBlob); The application provides pCSMIME similarly to the way that it is provided to CSM_SignMsg::Sign. The application also provides certs and CRLs (if any) that should be included in the SignedData->certificates. Sign will use m_snaccSignedData, pCSMIME, and pMsgCertCrls to generate the resulting ASN.1 encoded ContentInfo/SignedData that will be returned in pEncodedBlob. 6.3.2 CSM_VerifyData The CSM_VerifyData class provides a very low-level method for the application to process a received ContentInfo/SignedData. The class provides public access to the SignedData m_snaccSignedData member that is the SNACC generated class representing the ASN.1 SignedData class that will be filled after constructing the class. The application can directly manipulate the m_snaccSignedData as desired. 6.3.2.1 CSM_VerifyData Construction Members void CSM_VerifyData::CSM_VerifyData(); void CSM_VerifyData::CSM_VerifyData(CSM_Buffer *pbfBlob); void CSM_VerifyData::CSM_VerifyData(CSM_Buffer *pbfBlob, CSMIME *pCSMIME); The application should provide the ASN.1 encoded ContentInfo/SignedData to the CSM_VerifyData constructor. The constructor will call PreProc which will ASN.1 decode the input and store the result in m_snaccSignedData. 6.3.2.2 CSM_VerifyData Attribute Members CSM_Buffer* CSM_VerifyData::ExtractSignerPublicKey( IssuerAndSerialNumber *issuerAndSerialNumber, CSM_MsgCertCrls *pMsgCertCrls); The application can use ExtractSignerPublicKey to extract the signer’s public key from the appropriate SignedData->signerInfo based on the provided values. CSM_Buffer* CSM_VerifyData::GetSignerInst(CSMIME *pCSMIME, SignerInfo *pSI); GetSignerInst returns a CSM_CSInst that has been marked applicable and can operate on the algorithms specified in the provided SignerInfo. 6.3.2.3 CSM_VerifyData::Verify SM_RET_VAL CSM_VerifyData::Verify(CSMIME *pCSMIME, CSM_Buffer *pEncodedBlob, CSM_MsgCertCrls *pMsgCertCrls, CSM_Buffer *pSignedReceipt); SM_RET_VAL CSM_VerifyData::Verify(CSMIME *pCSMIME, SignerInfo *pSI, CSM_MsgCertCrls *pMsgCertCrls, CSM_Buffer *pSignedReceipt); SM_RET_VAL CSM_VerifyData::Verify(CSM_CSInst *pCSInst, CSM_MsgCertCrls *pMsgCertCrls, CSM_Buffer *pSignedReceipt); SM_RET_VAL CSM_VerifyData::Verify(CSMIME *pCSMIME, CSM_MsgCertCrls *pMsgCertCrls, CSM_Buffer *pSignedReceipt); There are several versions of CSM_VerifyData::Verify that the application may use depending on it’s needs. In General, the following parameters are used as described. Verify uses the incoming pMsgCertCrls as the validated originator cert path. Verify uses pCSMIME to access the instances needed for verification. The application can provide the ASN.1 encoded SignedData in the pEncodedBlob if it isn’t provided through the constructor. The application can specify which signer info to verify using the pSI parameter. A signed receipt, if requested/generated is returned in pSignedReceipt. See the description of CSM_VerifyMsg::Sign for more information. 6.3.2.4 CSM_VerifyData::PreProc SM_RET_VAL CSM_VerifyData::PreProc(CSMIME *pCSMIME); SM_RET_VAL CSM_VerifyData::PreProc(CSM_Buffer *pBlob); SM_RET_VAL CSM_VerifyData::PreProc(CSMIME *pCSMIME, CSM_Buffer *pBlob); Depending on the constructor you use, PreProc may be called automatically. The application can directly use PreProc to do “pre-processing” on the provided ASN.1 encoded SignedData. This step includes ASN.1 decoding the SignedData. After decoding, the values of the SignedData are directly accessable via the m_SnaccSignedData member. Pre-processing, if provided a pCSMIME, will match instances that are capable of processing the SignedData and mark them as applicable. 6.3.3 CSM_EncryptData The CSM_EncryptData class provides a very low-level method for the application to generate a ContentInfo/EnvelopedData. The class provides public access to the EnvelopedData m_snaccEnvelopedData member which is the SNACC generated class representing the ASN.1 EnvelopedData type. The application can directly fill in the m_snaccEnvelopedData as desired. 6.3.3.1 CSM_EncryptData::Encrypt SM_RET_VAL CSM_EncryptData::Encrypt(CSMIME *pCSMIME, CSM_MsgCertCrls *pMsgCertCrls, CSM_Recipients *pRecipients, CSM_OID *poidContentType, CSM_Buffer *pContent, CSM_Alg *pContentEncryptionAlg, CSM_Buffer *pbfOutput); Encrypt uses the incoming pCSMIME, pMsgCertCrls, and pRecipients to encrypt the content and protect the keys for the generated ContentInfo/EnvelopedData. The content is encrypted with the algorithm identified by pContentEncryptionAlg. The content is provided via pContent and is identified by poidContentType. The processing done by Encrypt is described in detail in the CSM_EncryptMsg class description. The resulting ASN.1 encoded ContentInfo/EnvelopedData will be returned in pbfOutput. 6.3.4 CSM_DecryptData The CSM_DecryptData class provides a very low-level method for the application to process a received ContentInfo/EnvelopedData. The class provides public access to the EnvelopedData m_snaccEnvelopedData member that is the SNACC generated class representing the ASN.1 EnvelopedData class that will be filled after constructing the class. The application can directly manipulate the m_snaccEnvelopedData as desired. 6.3.4.1 CSM_DecryptData Construction Members CSM_DecryptData::CSM_DecryptData(); CSM_DecryptData::CSM_DecryptData( CSM_Buffer *pbufEnvelopedData); CSM_DecryptData::CSM_DecryptData(CSM_Buffer *pbufEnvelopedData, CSMIME *pCSMIME); The application may use the first constructor to create an empty/clear object. The application may use the second constructor to create an object and set the ASN.1 encoded ContentInfo/EnvelopedData into it. The application may use the third constructor to do the same thing as the second constructor but also pre- process the EnvelopedData using the current set of instances in the CSMIME parameter. See PreProc for more pre-processing details. 6.3.4.2 CSM_DecryptData Attribute Members void CSM_DecryptData::Decode(CSM_Buffer *pbufEnvelopedData); Decode decodes the provided ASN.1 encoded ContentInfo/EnvelopedData and stores the result in the m_SnaccEnvelopedData public member. 6.3.4.3 CSM_DecryptData::Decrypt SM_RET_VAL CSM_DecryptData::Decrypt(CSMIME *pCSMIME, CSM_CertificateChoiceLst *pOrigCerts, CSM_Buffer *pbufDecryptedContent); The application uses Decrypt to decrypt the encrypted content from the EnvelopedData. Decrypt uses CSMIME and pOrigCerts to do the decryption. The resulting plain text is returned in pbufDecryptedContent. See the description of CSM_DecryptMsg::Decrypt for detailed information on the process. 6.4 The Low Level Component Classes The low-level component classes are classes that the message classes either use or are derived from. The application may interact with some or all of these classes depending on what the application needs to do. 6.4.1 CSM_MsgAttributes The CSM_MsgAttributes class encapsulates all of the attributes that may be in a SignedData for the application. It includes the attribute list that the application can directly access. It also includes a set of attribute members that the application can use to find attributes in the list. 6.4.1.1 CSM_MsgAttributes Construction Members TBD 6.4.1.2 CSM_MsgAttributes Attribute Members CSM_Attrib* CSM_MsgAttributes::FindAttribute(CSM_OID *pOID); The application may use the FindAttribute member to find and return the requested attribute from the list. The search is done based on the provided OID. If the attribute cannot be found, the return value is NULL. CSM_Buffer* CSM_MsgAttributes::GetMessageDigest(); char* CSM_MsgAttributes::GetSigningTime(); CSM_MsgSignerInfo* CSM_MsgAttributes::GetCounterSignature(); CSM_ReceiptRequest* CSM_MsgAttributes::GetReceiptRequest(); SM_RET_VAL CSM_MsgAttributes::GetContentHints( long &lDirStringType, char *&pszDirString, bool &bReceipt); CSM_SecLbl* CSM_MsgAttributes::GetSecurityLabel(); CSM_MlLst* CSM_MsgAttributes::GetMailList(); CSM_GeneralAsn* CSM_MsgAttributes::GetGeneralAsn(); CSM_Buffer* CSM_MsgAttributes::GetContentIdentifier(); CSM_OID* CSM_MsgAttributes::GetContentType(); CSM_Capabilities* CSM_MsgAttributes::GetCapabilities(); The application can use any of the GetX members to retrieve the attribute X. All members return the requested attribute or NULL if it cannot be found. The exception is GetContentHints which returns three parameters. GetContentHints returns SM_NO_ERROR if it succeeds. 6.4.2 CSM_Attrib The CSM_Attrib class is used to represent a single attribute for a SignedData. 6.4.2.1 CSM_Attrib Construction Members CSM_Attrib::CSM_Attrib(); CSM_Attrib::CSM_Attrib(long lFlag, CSM_Buffer *pMDigestOrContentID); CSM_Attrib::CSM_Attrib(char *pSigningTime); CSM_Attrib::CSM_Attrib(CSM_CounterSignature *pCounterSignature); CSM_Attrib::CSM_Attrib(CSM_ReceiptRequest *pReceiptRequest); CSM_Attrib::CSM_Attrib(CSM_ContentHints *pContentHints); CSM_Attrib::CSM_Attrib(CSM_SecLbl *pSecLbl); CSM_Attrib::CSM_Attrib(CSM_MlLst *pMlLst); CSM_Attrib::CSM_Attrib(CSM_GeneralAsn *pGeneralAsn); CSM_Attrib::CSM_Attrib(CSM_OID *pContentType); CSM_Attrib::CSM_Attrib(CSM_Capabilities *pCapabilities); The application may use any appropriate CSM_Attrib constructor to create that specific attribute. The only constructor in which there is ambiguity is the second constructor that takes a long and a CSM_Buffer as parameters. In this constructor’s case, if lFlag is set to SM_MESSAGE_DIGEST then CSM_Buffer is assumed to contain the MessageDigest. If lFlag is set to SM_CONTENT_IDENTIFIER then CSM_Buffer is assumed to contain the ContentIdentifier. Both the MessageDigest and ContentIdentifier are ASN.1 OCTET STRINGs. 6.4.2.2 CSM_Attrib Attribute Members The CSM_Attrib class includes the following public members: ? int m_nContentType: enum value indicating which attribute is in the union (see below). ? union m_uAttrib: union containing one of the following: ? CSM_Buffer *pMessageDigest ? CSM_Buffer *pSigningTime ? CSM_CounterSignature *pCounterSignature ? CSM_ReceiptRequest *pReceiptRequest ? CSM_ContentHints *pContentHints ? CSM_SecLbl *pSecLbl ? CSM_MlLst *pMlExpHist ? CSM_GeneralAsn *pGeneralAsn ? CSM_OID *pContentType ? CSM_Buffer *pContentIdentifier ? CSM_Capabilities *pCapabilities ? char *pszCSInst: Instance ID for signer info that will contain this attribute. If it is NULL, this attribute will be included in all generated SignerInfos. 6.4.3 CSM_CounterSignature The CSM_CounterSignature class represents the counter signature attribute that can be added to the unauthenticated attributes of a SignedData. 6.4.3.1 CSM_CounterSignature Construction Members TBD 6.4.3.2 CSM_CounterSignature Attribute Members CSM_MsgSignerInfo* CSM_CounterSignature::GetCounterSignature(); The application can use GetCounterSignature to retrieve the actual counter signature from the CSM_CounterSignature attribute class. 6.4.3.3 CSM_CounterSignature::GenerateCounterSignature SM_RET_VAL CSM_CounterSignature::GenerateCounterSignature( CSM_CSInst *pInst, CSM_MsgSignerInfo *pSignerInfo); GenerateCounterSignature uses the provided instance and the provided pSignerInfo to generate a new signer info that is the counter signature. GetCounterSignature can be used to retrieve the new signer info (counter signature). 6.4.4 CSM_ReceiptRequest The CSM_ReceiptRequest class represents the receipt request attribute that the application uses to indicate that a SignedData is requesting a signed receipt from the recipient(s). 6.4.4.1 CSM_ReceiptRequest Construction Members TBD 6.4.4.2 CSM_ReceiptRequest AttributeMembers TBD 6.4.5 CSM_ContentHints The CSM_ContentHints class represents the content hints attribute. 6.4.5.1 CSM_ContentHints Construction Members TBD 6.4.5.2 CSM_ContentHints Attribute Members TBD 6.4.6 CSM_SecLbl The CSM_SecLbl class represents the security label that can be applied to a SignerInfo in a SignedData. 6.4.6.1 CSM_SecLbl Construction Members TBD 6.4.6.2 CSM_SecLbl Attribute Members TBD 6.4.7 CSM_MlLst The CSM_MlLst class represents the mail list expansion history that can be added to a SignerInfo in a SignedData. 6.4.7.1 CSM_MlLst Construction Members TBD 6.4.7.2 CSM_MlLst Attribute Members TBD 6.4.8 CSM_GeneralAsn The CSM_GeneralAsn class represents a SignedData SignerInfo attribute that is unknown and cannot be ASN.1 decoded/encoded. It assumes that its value has already been ASN.1 encoded if originating this attribute. It assumes that the application will be able to ASN.1 decode its value if the application is interested in receiving/processing the attribute. 6.4.8.1 CSM_GeneralAsn Construction Members TBD 6.4.8.2 CSM_GeneralAsn AttributeMembers TBD 6.4.9 CSM_Capabilities The CSM_Capabilities class represents the S/MIME Capabilities attribute defined in [SMIME3]. 6.4.9.1 CSM_Capabilities Construction Members TBD 6.4.9.2 CSM_Capabilities Attribute Members TBD 6.4.10 CSM_CntType 6.4.10.2 CSM_CntType Attribute Members TBD 6.4.11 CSM_MsgSignerInfos The CSM_MsgSignerInfo class represents the SignerInfos in a SignedData in a received message. After constructing a CSM_VerifyMsg class, the application may use the CSM_MsgSignerInfo class contained therein to access the SignerInfos of that SignedData. 6.4.11.1 CSM_MsgSignerInfos Attribute Members CSM_MsgSignerInfo* CSM_MsgSignerInfos::GetNextApplicable (CSMIME *pCSMIME); CSM_MsgSignerInfo* CSM_MsgSignerInfos::GetFirstApplicable (CSMIME *pCSMIME); The application may use the GetNextApplicable and GetFirstApplicable attribute members to retrieve the CSM_MsgSignerInfo that are applicable in light of the instances passed into these members via the pCSMIME parameter. In other words, if pCSMIME contains only an RSA-capable instance and the application has a SignerInfo that contains an DSA signature and another SignerInfo that contains an RSA signature, then using the GetFirstApplicable member would return the SignerInfo containing the RSA signature since that is the only “applicable” signature that can be verified with the current instances. 6.4.12 CSM_MsgSignerInfo CSM_MsgSignerInfo represents a single SignerInfo from the SignedData. 6.4.12.1 CSM_MsgSignerInfo Construction Members CSM_MsgSignerInfo::CSM_MsgSignerInfo(); CSM_MsgSignerInfo::CSM_MsgSignerInfo(SignerInfo *pSignerInfo); The constructor of a CSM_MsgSignerInfo requires a SignerInfo (snacc generated class) as input unless the empty constructor is used. If a SignerInfo is provided, the CSM_MsgSignerInfo is constructed based on that SignerInfo. Then the members of CSM_MsgSignerInfo can be used to more easily access the SignerInfo. 6.4.12.2 CSM_MsgSignerInfo Attribute Members CSM_IssuerAndSerialNumber* CSM_MsgSignerInfo::GetIssuerAndSerialNumber(); CSM_Alg* CSM_MsgSignerInfo::GetDigestID(); CSM_Alg* CSM_MsgSignerInfo::GetSignatureID(); The application can use the above three attribute members to retrieve the respective components of the SignerInfo. GetIssuerAndSerialNumber returns a class containing the issuer name and serial number of the cert that generated the signature in the SignerInfo. GetDigestID returns the OID and parameters for the digest algorithm used. GetSignatureID returns the OID and parameters for the signature algorithm used. Bool CSM_MsgSignerInfo::WasVerified(); The application can call WasVerified to determine if the signature in the CSM_MsgSignerInfo was verified by CSM_VerifyMsg::Verify. 6.4.13 CSM_MsgCertCrls The CSM_MsgCertCrls class is intended to be a general purpose storage class for Certificates and CRLs. 6.4.13.1 CSM_MsgCertCrls Construction Members CSM_MsgCertCrls::CSM_MsgCertCrls(); CSM_MsgCertCrls::CSM_MsgCertCrls( CSM_CertificateChoiceLst *pCerts); CSM_MsgCertCrls::CSM_MsgCertCrls(CSM_BufferLst *pCerts); CSM_MsgCertCrls::CSM_MsgCertCrls(CertificateSet *pCertificateSet); This default constructor clears the contents of the CSM_MsgCertCrls object. The other constructors fill this object from the provided data. CertificateSet is a SNACC generated class. 6.4.13.2 CSM_MsgCertCrls Attribute Members CSM_CertificateChoiceLst* CSM_MsgCertCrls::GetCertificates(); void CSM_MsgCertCrls::SetCertificates( CSM_CertificateChoiceLst *pCerts); void CSM_MsgCertCrls::SetCertificates(CSM_BufferLst *pCerts); CSM_BufferLst* CSM_MsgCertCrls::GetCRLs(); void CSM_MsgCertCrls::SetCRLs(CSM_BufferLst *pCRLs); CSM_CertificateChoiceLst* CSM_MsgCertCrls::GetACs(); void CSM_MsgCertCrls::SetACs(CSM_CertifcateChoiceLst *pACs); The application can set the certs, ACs and crls in this class using SetCertificates, SetACs and SetCRLs. Likewise, the application can retrieve the certs, ACs and crls using GetCertificates, GetACs and GetCRLs. void CSM_MsgCertCrls::AddCert(CSM_CertificateChoice *pCert); The application may use AddCert to add a single certificate to the appropriate location in this object. void CSM_MsgCertCrls::ClearCerts(); void CSM_MsgCertCrls::ClearACs(); void CSM_MsgCertCrls::ClearCRLs(); The application may use ClearCerts, ClearACs, and ClearCRLs to clear the appropriate components of this object. void CSM_MsgCertCrls::PutSNACCCerts( CertificateSet *&pCertificateSet); void CSM_MsgCertCrls::SetSNACCCerts( CertificateSet *pCertificateSet); void CSM_MsgCertCrls::SetSNACCCrls( CertificateRevocationLists *pCrls); The application may use PutSNACCCerts, SetSNACCCerts, and SetSNACCCrls to load and retrieve data from this object using SNACC generated classes. The Put function decodes the certs in this object and loads their decoded values into the provided (or allocated) CertificateSet. The Set functions take the provided data and store it in the appropriate places in this object. 6.4.14 CSM_CertificateChoice The CSM_CertificateChoice class is intended to be a general purpose storage class for certificates. This class contains a CSM_Buffer that contains a single ASN.1 encoded certificate. It also includes an enumerated long that indicates what type of cert is in the buffer. Note that a CSM_CertificateChoiceLst is a CSM_List of CSM_CertificateChoice classes. See CSM_List for details. 6.4.14.1 CSM_CertificateChoice Construction Members CSM_CertificateChoice::CSM_CertificateChoice(); CSM_CertificateChoice::CSM_CertificateChoice(CSM_Buffer *pCert); CSM_CertificateChoice::CSM_CertificateChoice(CSM_Buffer *pCert, long lType); CSM_CertificateChoice::CSM_CertificateChoice( CertificateChoices &SNACCCertChoices); CSM_CertificateChoice::CSM_CertificateChoice( CSM_CertificateChoice &certChoice); The first constructor creates an empty class. The second constructor creates a CSM_CertificateChoice based on an encoded X.509 certificate. The third constructor gives the caller the ability to specify what is in the encoded buffer (cert or attribute cert). The fourth constructor allows the caller to create a CSM_CertificateChoice based on a previously decoded snacc certificate choice structure. The fifth constructor is the copy constructor. 6.4.14.2 CSM_CertificateChoice Attribute Members CSM_Buffer* CSM_CertificateChoice::GetEncodedCert(); void CSM_CertificateChoice::SetEncodedCert(CSM_Buffer *pCert); void CSM_CertificateChoice::SetEncodedCert(CSM_Buffer *pCert, long lType); void CSM_CertificateChoice::SetSNACCCertChoices( CertificateChoices &SNACCCertChoices); CSM_OID* CSM_CertificateChoice::GetKeyOID(); CSM_Buffer* CSM_CertificateChoice::GetPublicKey(); CSM_DN* CSM_CertificateChoice::GetIssuer(); CSM_DN* CSM_CertificateChoice::GetSubject(); CSM_Buffer* CSM_CertificateChoice::GetSerial(); CSM_Alg* CSM_CertificateChoice::GetPublicKeyAlg(); GetEncodedCert returns a pointer to the ASN.1 encoded certificate in this class. SetEncodedCert allows the caller to put an ASN.1 encoded cert into the class. SetSNACCCertChoices allows the caller to put a snacc decoded cert into the class. GetKeyOID returns the subject public key OID from the cert. GetPublicKey returns the subject public key from the cert. GetIssuer and GetSubject return CSM_DN classes containing the issuer DN and subject DN respectively. GetSerial returns the serial number from the cert. GetPublicKeyAlg returns the subject public key algorithm identifier in a CSM_Alg object. 6.4.15 CSM_List CSM_List is a template class for lists of objects. The declaration of the template class is: template class CSM_List 6.4.15.1 CSM_List Construction Members CSM_List::CSM_List(); CSM_List::CSM_List(T *t); The application can use the first constructor to create a list that is empty. The application can use the second constructor to create a list with the first node in place. 6.4.15.2 CSM_List Attribute Members void CSM_List::SelfDestruct(); void CSM_List::DestroyList(); SelfDestruct is used by the destuctor of this class and should generally not be used by the application. The application may use DestroyList to free every node of the list except for the first. DestroyList frees the contents of the first node leaving just a single empty node. void CSM_List::Append(T *t); void CSM_List::Append(CSM_List *l); The application can use Append to add a node t to the end of the list. The application can use the second form of Append to append another list (l) to the current list. SM_RET_VAL CSM_List::Length(); The application can use Length to calculate the length (number of nodes) in the list. CSM_List* CSM_List::First(); CSM_List* CSM_List::Last(); CSM_List* CSM_List::Next(); CSM_List* CSM_List::Prev(); The application can use First, Last, Next, and Prev to navigate through the list. Each attribute member returns a pointer to the appropriate node. For example, First returns a pointer to the first node. Prev returns a pointer to the previous node. T* CSM_List::Get(); void CSM_List::Set(T *t); The application can use Get to retrieve the contents of the current node. The application can use Set to set (store) t into the current node. The application should use the navigation members described previously to get to the node that it wants to store t in prior to using Set. (The same applies as appropriate for Get) 6.4.16 CSM_CommonData The CSM_CommonData class contains the “common data” for many types. 6.4.16.1 CSM_CommonData Construction Members CSM_CommonData::CSM_CommonData(); This constructor clears the CSM_CommonData object. 6.4.16.2 CSM_CommonData Attribute Members CSM_Buffer* CSM_CommonData::GetEncodedBlob(); void CSM_CommonData::SetEncodedBlob(CSM_Buffer *pBlob); void CSM_CommonData::SetEncodedBlob(CSM_Content *pContent); The application can get the “Encoded Blob” from a common data with the GetEncodedBlob member. The encoded blob would be available after doing the operation step of originating a message. For example, the ASN.1 encoded ContentInto/SignedData would be available after calling the Sign operation. Likewise, the ASN.1 encoded ContentInfo/EnvelopedData would be available after calling the Encrypt operation. The application should set the “Encoded Blob” when it receives a message to be processed. The “encoded blob” might be an ASN.1 encoded ContentInfo/SignedData or ContentInfo/EnvelopedData. CSM_Content* CSM_CommonData::GetEncapContent(); void CSM_CommonData::SetEncapContent(CSM_Content *pContent); void CSM_CommonData::SetEncapContent(CSM_Buffer *pContent); The application can get the encapsulated content using GetEncapContent. This would typically be done after processing a received message. For example, this would be done after verifying a signature or decrypting a message. The application can Set the encapsulated content using SetEncapContent prior to doing the operation step of originating a message. For example, the application could set the encapsulated content of a SignedData or EnvelopedData before using the Sign or Encrypt operational members. void CSM_CommonData::SetContentType(CSM_OID *pContentType); The application uses SetContentType to set the OID identifying the content type. 6.4.17 CSM_Content The CSM_Content class represents the “inner content” of a ContentInfo. It is contained in the CSM_CommonData class that is derived by CSM_ContentInfoMsg, CSM_SignMsg, CSM_VerifyMsg, CSM_EncryptMsg, and CSM_DecryptMsg. 6.4.17.1 CSM_Content Construction Members CSM_Content::CSM_Content(); CSM_Content::CSM_Content(char *pszContent); CSM_Content::CSM_Content(CSM_Buffer *pContent); CSM_Content::CSM_Content(CSM_Buffer *pContent, CSM_OID &tOID); CSM_Content::CSM_Content(CSM_Content *pContent); The application can use whatever constructor is easiest to create a content. Normally, the application would not directly create a content but would instead create a high level message class which would eventually result in the creation of a content inside the high level message class. 6.4.17.2 CSM_Content Attribute Members void CSM_Content::SetContent(char *pszContent); void CSM_Content::SetContent(CSM_Buffer *pContent); void CSM_Content::SetContent(CSM_Content *pContent); void CSM_Content::SetContent(CSM_Buffer *pContent, CSM_OID &tOID); The application can directly set the content using SetContent. Normally, though, the content would be set through the construction of a high level message class. CSM_Content contains the following public members that the application can use: ? CSM_OID m_ContentType: The OID of the (inner) content. ? long m_lType: an enumerated value (see class definition) indicating the type of (inner) content. ? CSM_Buffer m_Content: The actual content itself. 6.4.18 CSM_IssuerAndSerialNumber The CSM_IssuerAndSerialNumber class encapsulates the snacc IssuerAndSerialNumber class. 6.4.18.1 CSM_IssuerAndSerialNumber Construction Members CSM_IssuerAndSerialNumber::CSM_IssuerAndSerialNumber(); CSM_IssuerAndSerialNumber::CSM_IssuerAndSerialNumber( CSM_DN &dn, CSM_Buffer &serial); CSM_IssuerAndSerialNumber::CSM_IssuerAndSerialNumber( CSM_Buffer *SNACCCert); CSM_IssuerAndSerialNumber::CSM_IssuerAndSerialNumber( IssuerAndSerialNumber &SNACCIssSn); CSM_IssuerAndSerialNumber::CSM_IssuerAndSerialNumber( Certificate &SNACCCert); The application can use the empty constructor to create a cleared CSM_IssuerAndSerialNumber. The second constructor creates a CSM_IssuerAndSerialNumber based on the provided DN and serial number. The third constructor creates a CSM_IssuerAndSerialNumber from the provided ASN.1 encoded cert. The fourth constructor creates a CSM_IssuerAndSerialNumber from the provided SNACC IssuerAndSerialNumber class. The fourth constructor creates a CSM_IssuerAndSerialNumber from a decoded SNACC certificate object. 6.4.18.2 CSM_IssuerAndSerialNumber Attribute Members CSM_DN* CSM_IssuerAndSerialNumber::GetIssuer(); CSM_Buffer* CSM_IssuerAndSerialNumber::GetSerialNo(); GetIssuer and GetSerialNo return the appropriate components of the CSM_IssuerAndSerialNumber. void CSM_IssuerAndSerialNumber::SetIssuer(CSM_DN &Issuer); void CSM_IssuerAndSerialNumber::SetIssuer(Name &SnaccIssuer); void CSM_IssuerAndSerialNumber::SetSerialNo(CSM_Buffer &SerialNo); The two variations of SetIssuer and the SetSerialNo member set the appropriate components of the CSM_IssuerAndSerialNumber based on the provided parameter. The following operators have been overridden for the CSM_IssuerAndSerialNumber class: ==, =, IssuerAndSerialNumber* 6.4.19 CSM_Recipient The CSM_Recipient class contains the RecipientInfo from the EnvelopedData that the application may need. CSM_Recipient is derived from CSM_CertificateChoice. 6.4.19.1 CSM_Recipient Construction Members CSM_Recipient::CSM_Recipient(); CSM_Recipient::CSM_Recipient(CSM_Buffer *pCert); CSM_Recipient::CSM_Recipient(CSM_Buffer *pCert, long lType); The first constructor clears the members of this object. The second two constructor’s create a recipient from the provided ASN.1 encoded certificate. 6.4.19.2 CSM_Recipient Attribute Members CSM_Entity* CSM_Recipient::GetOriginatorEntity(); CSM_Alg* CSM_Recipient::GetKeyEncryptionAlg(); CSM_IssuerAndSerialNumber* CSM_Recipient:: GetIssuerAndSerial(); GetOriginatorEntity returns the Entity from a recipient. GetKeyEncryptionAlgorithm returns the CSM_Alg containing the key encryption algorithm identifier for a recipient. GetIssuerAndSerial returns the CSM_IssuerAndSerialNumber of the recipient. Generally, the above described Get attribute members are used when processing a received EnvelopedData. bool CSM_Recipient::WasDecrypted(); After processing an EnvelopedData, the application can use this attribute member to determine whether or not the content was decrypted using the decrypted MEK from this recipient. 6.4.20 CSM_UserKeyMaterial The CSM_UserKeyMaterial class encapsulates UKM. It contains to public member variables that the application may look at which are: ? CSM_Alg *m_pAlgorithm: The UKM’s algorithm identifier. ? CSM_Buffer *m_pUKM: The UKM, generally produced by the SMTI_GenerateEMEK function (CTI Library). With the SFL, the UKMs are generally used internally so the application will not have to use them. 6.4.21 CSM_OriginatorInfo The CSM_OriginatorInfo class encapsulates the OriginatorInfo in an EnvelopedData. Generally, the application will use this class from the CSM_DecryptMsg class to access the originator’s information including the originator’s certificates. The application can use the GetOriginatorDns member to get the DN’s of the originator’s of the message from this object. Alternately, the application may directly access the CSM_MsgCertCrls. 6.4.22 CSM_Buffer The CSM_Buffer class is the general memory/buffer class used throughout the SFL. CSM_Buffer has support for a variety of capabilities including file style IO and storage either in memory or file. 6.4.22.1 CSM_Buffer Construction Members CSM_Buffer::CSM_Buffer(); CSM_Buffer::CSM_Buffer(SM_SIZE_T lSize); CSM_Buffer::CSM_Buffer(char *pszFileName); CSM_Buffer::CSM_Buffer(char *pBuf, long lSize); CSM_Buffer(CSM_Buffer &b); The application can use the first constructor to create an uninitialized buffer. The second constructor creates an initialized buffer with its storage in memory of size lSize. The third constructor creates an initialized buffer with its storage in the file specified by pszFileName. The fourth constructor creates a buffer in memory and copies the provided buffer pBuf of size lSize into the buffer. The fifth constructor creates a buffer based on the provided buffer. 6.4.22.2 CSM_Buffer Attribute Members SM_SIZE_T CSM_Buffer::Length(); Length returns the length of the data in the buffer. It returns 0 if there is no data in the buffer. char* CSM_Buffer::AccessAll(); char* CSM_Buffer::CopyAll(); char* CSM_Buffer::CopyAll(SM_SIZE_T &l); AccessAll returns a pointer to the actual storage of the buffer. If the buffer is stored in file, it reads the file into memory and returns a pointer to that memory. CopyAll returns a copy of the actual storage of the buffer. CopyAll(SM_SIZE_T &l) returns a copy of the actual storage of the buffer and returns the size of the storage in l. void CSM_Buffer::Set(char *psz); void CSM_Buffer::Set(char *p, SM_SIZE_T lSize); void CSM_Buffer::SetLength(SM_SIZE_T lSize); void CSM_Buffer::SetFileName(char *pszFN); The first Set stores a null terminated string in memory in the buffer. The second Set stores a buffer of size lSize in the buffer. SetLength forces the size to lSize. SetFileName sets the file name for a file buffer. long CSM_Buffer::Compare(CSM_Buffer &b); SM_RET_VAL CSM_Buffer::ReSet(CSM_Buffer &b); Compare compares this buffer with the buffer specified by b. It returns 0 if they are identical (regardless of whether the buffer storage is in file or memory). It returns a negative number if this buffer is less than b. It returns a positive number if this buffer is greater than b. ReSet makes a copy of this buffer and puts the results in b. char* CSM_Buffer::Alloc(SM_SIZE_T lSize); Alloc allocates temporary memory in the buffer’s cache which can then be used by the application. This member should be used in conjunction with Open, Flush, and Close, otherwise the data in the cache will be lost when the buffer is destroyed. long CSM_Buffer::ConvertFileToMemory(); long CSM_Buffer::ConvertMemoryToFile(char *pszFN); The application can use these members to convert the buffer storage mechanism to the alternate type. If converting to file, the application must provide a file name. 6.4.22.3 CSM_Buffer File Style IO Operational Members These members treat the buffer like a file although the actual storage may be in memory or in a file. long CSM_Buffer::Open(char *pszMode); The application must open the buffer before calling bSeek, bRead, bWrite, or bClose on the buffer. The pszMode parameter is the same format as that used by fopen. long CSM_Buffer::Seek(SM_SIZE_T lOffset, SM_SIZE_T lOrigin); The application can seek through the buffer using bSeek. The application must set lOrigin to SM_START (start of buffer), SM_CURRENT (current position in buffer), or SM_END (end of buffer). The application must set lOffset to the desired offset from lOrigin. If the application specified SM_END as the lOrigin, then lOffset is used in reverse (i.e. moving back through the buffer). long CSM_Buffer::cRead(char *pBuffer, SM_SIZE_T lSize); char* CSM_Buffer::nRead( SM_SIZE_T lSize, SM_SIZE_T &lBytesRead); long CSM_Buffer::Write(char *pBuffer, SM_SIZE_T lSize); void CSM_Buffer::Flush(); The application can write to the buffer at the current position using Write. The application can read from the buffer at the current position using cRead or nRead. cRead copies the data from the buffer and the application is responsible for allocating and freeing the memory returned. nRead returns a pointer to the data in the buffer and the application must not free the memory. Flush writes whatever data is in the Cache (allocated by Alloc) into the buffer. void CSM_Buffer::Close(); The application must call bClose on the buffer if it called bOpen on the buffer. 6.4.22.4 CSM_Buffer Overridden Operators The char*, unsigned char*, and const unsigned char* operators are overridden to return AccessAll(). The == operator is overridden to use Compare. The != operator is overridden to use !Compare. The = operator is overridden to use ReSet. 6.4.23 CSM_OID The CSM_OID class is used to represent an Object Identifier throughout the SFL. CSM_OID is derived from the SNACC AsnOid class. 6.4.23.1 CSM_OID Construction Members CSM_OID::CSM_OID(); CSM_OID::CSM_OID(char *); CSM_OID::CSM_OID(const AsnOid &o); The second constructor accepts a character string as input. The character string represents the OID in dot notation (e.g. 1.2.840.113549.2.5). The third constructor creates the CSM_OID based on the provided snacc AsnOid class. 6.4.23.2 CSM_OID Attribute Members char* CSM_OID::GetChar(); The application can use GetChar to retrieve the dot notation representation of the OID. Likewise, cast operators char* and const char* use GetChar to return the dot notation representation of the OID. SM_RET_VAL CSM_OID::PutChar(char *szOidCopy); PutChar stores the provided dot-notation OID in the CSM_OID. 6.4.23.3 CSM_OID Overridden Operators The =, char*, const char*, ==, and != operators are overriden in CSM_OID. 6.4.24 CSM_DN The CSM_DN class encapsulates a DN and provides members to access, use, and set its contents. 6.4.24.1 CSM_DN Construction Members CSM_DN::CSM_DN(); CSM_DN::CSM_DN(CSM_Buffer *pDN); CSM_DN::CSM_DN(Name &issuer); The first constructor clears the object’s members. The second constructor creates the DN based on the provided ASN.1 encoded DN. The third constructor creates the DN based on the SNACC Name class. 6.4.21.2 CSM_DN Attribute Members char* CSM_DN::GetDNString(); void CSM_DN::SetEncodedDN(CSM_Buffer &encodedDN); CSM_Buffer* CSM_DN::GetEncodedDN(); void CSM_DN::Decode(); GetDNString returns a string representation of the DN. SetEncodedDN accepts a buffer containing an ASN.1 encoded DN and stores it in this object. GetEncodedDN returns a pointer to an ASN.1 encoded DN. Decode ASN.1 decodes the DN. The following operators have been overridden for CSM_DN: ==, =, and Name* 6.4.25 CSM_Alg The CSM_Alg class encapsulates an Algorithm and provides members to access, use, and set its contents which consist primarily of the Algorithm OID and associated parameters. 6.4.25.1 CSM_Alg Construction Members CSM_Alg::CSM_Alg(); CSM_Alg::CSM_Alg(CSM_OID &AlgOid); CSM_Alg::CSM_Alg(AlgorithmIdentifier &SNACCAlgId); The first constructor clears the object’s members. The second constructor creates the CSM_Alg based on the provided OID leaving the parameters empty. The third constructor creates the CSM_Alg based on the provided SNACC AlgorithmIdentifier class. 6.4.25.2 CSM_Alg Attribute Members CSM_OID* CSM_Alg::GetId(); CSM_Buffer* CSM_Alg::GetParams(); AlgorithmIdentifier* CSM_Alg::GetSNACCAlgId(); SM_RET_VAL CSM_Alg::PutSNACCAlg(AlgorithmIdentifier *pSNACCAlg); GetID returns the OID from the CSM_Alg. GetParams returns the ASN.1 encoded parameters from the CSM_Alg. The application can use GetSNACCAlgId or PutSNACCAlg to get or put AlgorithmIdentifier classes. The following operators have been overridden for CSM_Alg: ==, != 6.4.26 Address Book Classes The SFL includes 2 “Address Book” classes. These classes provide a simple database mechanism for storing certificates and PKCS#8 information. The first class MAB_AB_def is the “container” address book. It contains zero to many MAB_Entrydef classes along with members to assist in using the address book. Each MAB_Entrydef contains information about a cert and associated PKCS#8 information. These classes are intended primarily for use by the CTI Classes so they will not be described further here. See the class definitions for more information. 6.5 The CSMIME Library Class The CSMIME class represents the SFL Library. It has the two primary purposes of containing the error information and containing the list of CSM_CSInst classes (instances). It has members to operate on this information. The CSMIME class should be constructed and initialized whenever an application that uses the SFL starts. 6.5.1 CSMIME Construction Members CSMIME::CSMIME(); The CSMIME() constructor clears the memory for the object. 6.5.2 CSMIME Attribute Members void CSMIME::ClearFlag(char chClearFlag); The application may use ClearFlag to clear the requested flags. The chClearFlag may be a combination of [SM_INST_APPLICABLE | SM_INST_USE_THIS | SM_INST_ALL] corresponding to all instances marked applicable, all instances marked UseThis, or all instances. See the CSM_CSInst description for details. SM_RET_VAL CSMIME::UseAll(); SM_RET_VAL CSMIME::UseAllSigners(); SM_RET_VAL CSMIME::UseAllSigners(CSM_Buffer *pCert); SM_RET_VAL CSMIME::UseAllSigners(CSM_BufferLst *pCerts); The application can use UseAll to mark all instances in the CSMIME for use. The application can use the UseAllSigners members to assist in marking instances (CSM_CSInst classes) for a signing operation. All three versions return the number of instances that were marked. UseAllSigners with no parameters marks every instance that has a DS private key. UseAllSigners with a single buffer containing an ASN.1 encoded certificate marks every instance that has a DS private key that matches the DS algorithm in the cert. UseAllSigners with a list of buffers containing ASN.1 encoded certificates marks every instance that has a DS private key that matches a DS algorithm in one of the provided certs. CSM_CSInst* CSMIME::FindCSInstAlgIds(CSM_Alg *pDigestAlg, CSM_Alg *pDigestEncryptionAlg, CSM_Alg *pKeyEncryptionAlg, CSM_Alg *pContentEncryptionAlg); The application can use FindCSInstAlgIds to help find the instances that it needs based on the provided algorithms. If, for example, the application wanted to find an instance that supported DSA signing, the application could call FindCSInstAlgIds passing the DSA signing OID for pDigestEncryptionAlg and NULL for the other three parameters. FindCSInstAlgIds would find the first instance that supported DSA signing and return a pointer to it. CSM_ErrorBuf* CSMIME::GetErrorBuf(); The application should use this member to access the error information class. See the description of CSM_ErrorBuf for detailed information. SM_RET_VAL CSMIME::SetCSInstVerify(CSM_VerifyMsg *pVerifyMsg); SM_RET_VAL CSMIME::SetCSInstDecrypt(CSM_DecryptMsg *pDecryptMsg); SetCSInstVerify will assign all appropriate CSInstances that can verify the signature of an incomming SignedData message. SetCSInstDecrypt will assign all appropriate CSM_CSInsts that can decrypt messages from the recipient(s) in CSM_DecryptMsg. This may entail searching among the various CSInstances for one or more of the intended recipients present in the message (based on the RecipientInfos in the received EnvelopedData message). If successful, the CSM_DecryptMsg->Decrypt() member function can be called; a CSInstance was located that matches one of the personalities in the message. If more than one recipient can be processed by this set of CSM_CSInsts, this function will choose the first valid recipient in the list; it is expected that the application will explicitely mark the appropriate CSM_CSInst if an alternate recipient is required. SM_RET_VAL CSMIME::FindCommonContentOID( CSM_BufferLst *pRecipCerts, CSM_OID *pContentEncryptOID); FindCommonContentOID will determine a common Content algorithm based on the specified recipient(s). If more than one recipient is specified, then an attempt is made to find a content encryption algorithm common to each pair-wise key encryption algorithm. void CSMIME::InstanceLock(char chLockFlag); void CSMIME::InstanceUnlock(char chLockFlag); The application may use InstanceLock and InstanceUnlock to lock or unlock all instances specified by the chLockFlag parameter. The chLockFlag parameter may be a combination of the following: [SM_INST_APPLICABLE | SM_INST_USE_THIS | SM_INST_ALL]. These flags correspond to instances marked applicable and/or UseThis or All instances. 6.6 The CSM_CSInst Class The CSM_CSInst class represents a Crypto Service Instance. The instance provides a way for the application to select and work with the crypto services that it wants to use. The list of instances is given to the SFL so that the SFL can use them to access the crypto services that the application wants to use. 6.6.1 CSM_CSInst Construction Members CSM_CSInst::CSM_CSInst(); This constructor clears the CSM_CSInst object. 6.6.2 CSM_CSInst Attribute Members char* CSM_CSInst::GetID(); void CSM_CSInst::SetID(char *pszCSInstID); Each instance gets a unique ID when it is created. The application can use this ID by calling GetID. The application can override the default ID and set a new one with SetID. The ID must be a null terminated string. void CSM_CSInst::UseThis(); void CSM_CSInst::DontUseThis(); bool CSM_CSInst::IsThisUsed(); bool CSM_CSInst::IsApplicable(); Each instance has two flags associated with it. The first is the “UseThis” flag. The application should set these prior to originating a message (signing or encrypting). Setting an instance to “UseThis” for signing indicates that the crypto services in that instance will be used to generate a SignerInfo for the resulting SignedData. CSM_SignMsg or CSM_SignData will generate a SignerInfo for every instance marked UseThis. Setting an instance to “UseThis” for encryption indicates that the crypto services in that instance may be used to encrypt a key to a recipient. The second flag (the applicable flag) is set by the “Pre-processing” step of receiving a message. The constructor of CSM_VerifyMsg or CSM_DecryptMsg usually does the pre-processing however it can be done explicitly by calling the PreProc member. The applicable flag indicates that that instance can be used to either verify a signature in a message or decrypt a key/content from the message. void CSM_CSInst::SetCertificates(CSM_BufferLst *pCertificates); void CSM_CSInst::SetCertificates(CSM_CertificateChoiceLst *pCertificates); CSM_CertificateChoiceLst* CSM_CSInst::GetCertificates(); The application can store and retrieve certificates from the instance using SetCertificates and GetCertificates. If the application wants to have just the user certificate included in a message, then it should put only the user certificate in the instance used for the message. If the application wants to have the entire cert path included in a message, then it should put the entire cert path in the instance used for the message. void CSM_CSInst::SetCRLs(CSM_BufferLst *pCRLs); CSM_BufferLst* CSM_CSInst::GetCRLs(); The application can store and retrieve associated CRLs from the instance using SetCRLs and GetCRLs. void CSM_CSInst::SetPreferredAlgs(COID oidDigest, COID oidDigestEncryption, COID oidKeyEncryption, COID oidContentEncryption); void CSM_CSInst::GetPreferredAlgs(COID *oidDigest, COID *oidDigestEncryption, COID *oidKeyEncryption, COID *oidContentEncryption); void CSM_CSInst::GetAlgs(CSM_Alg_lst **ppdigestAlgID, CSM_Alg_lst **ppdigestEncryptionAlgID, CSM_Alg_lst **ppkeyEncryptionAlgID, CSM_Alg_lst **ppcontentEncryptionAlgID); bool CSM_CSInst::FindAlgs(CSM_Alg *pdigestAlgID, CSM_Alg *pdigestEncryptionAlgID, CSM_Alg *pkeyEncryptionAlgID, CSM_Alg *pcontentEncryptionAlgID); The application can use SetPreferredAlgs to specify which algorithm ID is the preferred one for an instance. If, for example, an instance supports both SHA1 and MD5, and SHA1 is the preferred algorithm, then the application could call SetPreferredAlgs passing the SHA1 OID for the oidDigest parameter and NULL for the other parameters. NULL passed as a parameter to any of these functions indicates that that parameter will be ignored. The application can find out which algorithm is the current preferred algorithm by calling GetPreferredAlgs. The application can get the algorithms supported by an instance by calling GetAlgs. The application can find out if the instance supports a particular algorithm by calling FindAlgs. 6.7 The Error Handling Class, CSM_ErrorBuf The CSM_ErrorBuf class is the container for error information. Typically, the application will retrieve error information from the CSM_ErrorBuf contained in the CSMIME class. 6.7.1 CSM_ErrorBuf Construction Members This constructor clears the CSM_ErrorBuf object. 6.7.2 CSM_ErrorBuf Attribute Members The CSM_ErrorBuf class contains the following public members that the application may use: ? long m_lErrorCode: the numerical error code that occurred. SM_NO_ERROR (0) indicates no error. ? CSM_Buffer *m_pErrorBuf: contains error data that the application may be interested in. For example, m_pErrorBuf may contain an ASN.1 encoded DN or Cert that caused an error. ? char *m_pszDebug: contains a null terminated string consisting of a full stack to the error. The “full stack” includes each function or member called in route to the error. Each function in the stack shows it’s function name, source file name and line number. 7. Error Handling Conventions Every SFL function returns a long value indicating the result of the function processing. A returned value of SM_NO_ERROR (0) indicates that an error did not occur and the function executed normally. If an error occurs, the function immediately terminates processing and returns a non-zero value indicating the type of error. All errors are fatal errors. The application is responsible for any required error recovery procedures including freeing all memory allocated for the parameters passed between the application and SFL functions (including linked lists). 8. SFL Cryptographic Token Interface (CTI) Libraries (TBD: All of this section needs work.) 8.1. SFL SM_RSA CTI Library The SFL SM_RSA CTI Library is one of the instantiations of the generic SFL CTI libraries called by the SFL High-Level functions. It provides an interface to the BSAFE library which performs the RSA-specific processing required to provide RSA security services. It uses the required private keys stored in an PKCS #8 encrypted key file. It supports MD5 and SHA1 for digesting. MD5 is the preferred digest algorithm. It supports RSA for digest encryption. It supports RSA for key encryption. It supports RC2 for content encryption. 8.2. SFL SM_Free CTI Library The SFL SM_Free CTI Library is one of the instantiations of the generic SFL CTI libraries called by the SFL High-Level functions. It provides an interface to the freeware Crypto++ library that performs the crypto processing required to provide S/MIME v3 MUST algorithm security services. It uses the required private keys stored in an PKCS#8 encrypted key file. It supports SHA1 and MD5 for digesting. It supports DSA for digest encryption. It supports DH/3DES for key encryption (key agreement, key encryption). It supports 3DES-CBC for content encryption. The SM_Free CTI Library derives its SHA1 support from the SM_Common CTI Class/Library. 8.3. SFL SM_Fort CTI Library The SFL SM_Fort CTI Library is one of the instantiations of the generic SFL CTI libraries called by the SFL High-Level functions. It provides an interface to the Fortezza Cryptologic Interface (CI) Library which performs the Fortezza-specific processing required to provide the DSA, KEA and Skipjack algorithms. It calls SHA-1 freeware to perform hashing. It uses the required private keys stored on the Fortezza Card. The SM_Fort CTI Library derives its SHA1 support from the SM_Common CTI Class/Library. 9. Possible Future Enhancements 1) The initial release of the SFL does not generate key material. Also, it does not generate certificate management messages. It can be used to protect certificate management messages within CMS objects. Support for generating key material and certificate management messages may be added in a later version of the SFL, but is not implemented in the initial SFL release. 2) The capability to generate countersignatures may be added in a later version of the API. 3) The capability to add signerInfos (i.e. additional signatures) to a signedData object may be added in a later version of the API, 4) SFL does not support Mail List keys. This capability may be added to a later release. 10. Point of Contact John Pawling (301) 953-3600 J.G. Van Dyke & Associates, Inc. (410) 880-6095 141 National Business Pkwy, Suite 210 FAX: (301) 953-2901 Annapolis Junction, MD 20701 jsp@jgvandyke.com APPENDIX A. Sending and Receiving S/MIME Messages This appendix provides general high-level descriptions of some examples of how an S/MIME application can use the SFL. This appendix applies to the use of both the C++ and C SFL APIs. The C and C++ API sections provide further details regarding how each API is used to support the general processes described in this appendix. A.1. Signed-Only S/MIME Message Figure A1 depicts the MIME encapsulation of a SignedData object. The original content is signed and encapsulated within the SignedData object. As per [SMIME3], the original content and the SignedData must be MIME encapsulated. This example depicts the CMS security services equivalent to a signed-only MSP security heading. The following sections provide examples of how to use the SFL to send and receive a signed-only S/MIME message. Figure A1. MIME Encapsulation of CMS Signed-Only Message A.1.1. Sending a Signed-Only S/MIME Message 1. Application encapsulates original content in MIME header. 2. Application initializes the cryptographic token to be used to sign the data (if not done already). 3. Application selects private key material to be used to sign the data. 4. Application fills in the data structures for the optional attributes to be included in the SignedData object such as: content type; security label; signed receipt request; content description; etc. 5. Application uses SM_Sign or CSM_SignMsg::Sign to produce the SignedData object encapsulating the MIME-encapsulated original content. 6. Application encapsulates SignedData object in MIME header and sends. A.1.2. Receiving a Signed-Only S/MIME Message 1. Application receives S/MIME message and parses outer MIME header. 2. Application recognizes MIME content type as a CMS object. 3. Application uses SFL to determine that the CMS object is a SignedData object. 4. Application uses SFL to decode the SignedData object to determine the identity of the signer(s), algorithms used to sign the data, contentType of encapsulated data, etc. 5. Application initializes the cryptographic token required to verify the SignedData (if not done already). 6. Application obtains and validates signer's X.509 Certification path (could use freeware CM Library CM_RetrieveKey function). 7. Application uses SM_Verify or CSM_VerifyMsg::Verify to validate the signature of the SignedData object. If a SignedData/Receipt is requested by the signer and the application has indicated that a SignedData/Receipt should be built (if requested), then the SFL generates it. The SFL can be used to access all attributes, such as the eSSSecurityLabel, included in the verified SignedData. 8. Application parses MIME header and recognizes content type as original content. A.2. Encrypted-Only S/MIME Message Figure A2 depicts the MIME encapsulation of an EnvelopedData object. The original content is encrypted and encapsulated within the EnvelopedData object. As per [SMIME3], the original content and the EnvelopedData must be MIME encapsulated. This example depicts the CMS security services equivalent to an encrypted-only MSP security heading. The following sections provide examples of how to use the SFL to send and receive an encrypted-only S/MIME message. Figure A2. MIME Encapsulation of CMS Encrypted-Only Message A.2.1. Sending an Encrypted-Only S/MIME Message. 1. Application encapsulates original content in MIME header. 2. Application initializes the cryptographic token required to encrypt the data (if not done already). 3. Application selects the list of recipients, and retrieves and validates the X.509 Certification Path for each recipient (could use freeware CM Library CM_RetrieveKey function). 4. If required for the key management (KM) algorithm (e.g. KEA, DH), the application selects the originator’s private key material to be used as part of the process to encrypt the message. 5. Application uses SM_Encrypt or CSM_EncryptMsg::Encrypt to produce the EnvelopedData object encapsulating the MIME-encapsulated original content. 6. Application encapsulates EnvelopedData in MIME header and sends. A.2.2. Receiving an Encrypted-Only S/MIME Message 1. Application receives S/MIME message and parses outer MIME header. 2. Application recognizes MIME content type as a CMS object. 3. Application uses SFL to determine that the CMS object is an EnvelopedData object. 4. Application uses SFL to decode the EnvelopedData object to determine the identity of the originator (if present), algorithms used to encrypt the data, contentType of encapsulated data, etc. 5. Application initializes the cryptographic token required to decrypt the EnvelopedData (if not done already). 6. If required for the KM algorithm, the application obtains and validates originator’s X.509 Certification Path (could use freeware CM Library CM_RetrieveKey function). 7. Application uses SM_Decrypt or CSM_DecryptMsg::Decrypt to decrypt the EnvelopedData content. 8. Application parses decrypted MIME header and recognizes content type as original content. A.3. Signed and Encrypted S/MIME Message Figure A3 provides an example of MIME encapsulation of multiple nested CMS- protected objects. It depicts the scenario in which the original content is signed and encapsulated within the SignedData object. Then the SignedData object is encrypted and encapsulated within an EnvelopedData object. As per [SMIME3], each layer is MIME encapsulated. This example depicts the CMS security services equivalent to a signed and encrypted MSP security heading. The following sections provide examples of how to use the SFL to send and receive a signed and encrypted S/MIME message. Figure A3. MIME Encapsulation of CMS Signed/Encrypted Message A.3.1. Sending a Signed and Encrypted S/MIME Message 1. Application encapsulates original content in MIME header. 2. Application initializes the cryptographic token (if not done already). 3. Application selects private key material to be used to sign the data. 4. Application fills in the data structures for the optional attributes to be included in the SignedData object such as: content type, security label; signed receipt request; content description, etc. 5. Application uses SM_Sign or CSM_SignMsg::Sign to produce the SignedData object encapsulating the MIME-encapsulated original content. 6. Application encapsulates SignedData object in MIME header. 7. Application selects the list of recipients, and retrieves and validates the X.509 Certification Path for each recipient (could use freeware CM Library CM_RetrieveKey function). 8. If required for the KM algorithm (e.g. KEA, DH), the application selects the originator’s private key material to be used as part of the process to encrypt the message. 9. Application uses SM_Encrypt or CSM_EncryptMsg::Encrypt to produce the EnvelopedData object encapsulating the MIME-encapsulated SignedData object 10. Application encapsulates EnvelopedData in MIME header and sends. A.3.2. Receiving a Signed and Encrypted S/MIME Message 1. Application receives S/MIME message and parses outer MIME header. 2. Application recognizes MIME content type as a CMS object. 3. Application uses SFL to determine that the CMS object is an EnvelopedData object. 4. Application uses SFL to decode the EnvelopedData object to determine the identity of the originator (if present), algorithms used to encrypt the data, contentType of encapsulated data, etc. 5. Application initializes the cryptographic token required to decrypt the EnvelopedData (if not done already). 6. If required for the KM algorithm, the application obtains and validates originator’s X.509 Certification Path (could use freeware CM Library CM_RetrieveKey function). 7. Application uses SM_Decrypt or CSM_DecryptMsg::Decrypt to decrypt the EnvelopedData content. 8. Application parses decrypted MIME header and recognizes content type as a CMS object. 9. Application uses SFL to determine that the CMS object is a SignedData object. 10. Application uses SFL to decode the SignedData object to determine the identity of the signer(s), algorithms used to sign the data, contentType of encapsulated data, etc. 11. Application initializes the cryptographic token required to verify the SignedData (if not done already). 12. Application obtains and validates signer's X.509 Certification path (could use freeware CM Library CM_RetrieveKey function). 13. Application uses SM_Verify or CSM_VerifyMsg::Verify to validate the signature of the SignedData object. If a SignedData/Receipt is requested by the signer and the application has indicated that a SignedData/Receipt should be built (if requested), then the SFL generates it. The SFL can be used to access all attributes, such as the eSSSecurityLabel, included in the verified SignedData. 14. Application parses MIME header and recognizes content type as original content. A.4. Signed/Encrypted/Signed S/MIME Message Figure A4 provides an example of MIME encapsulation of multiple nested CMS- protected objects. It depicts the scenario in which the original content is signed and encapsulated within the inner SignedData object. The inner SignedData is then encrypted and encapsulated within an EnvelopedData object. The EnvelopedData object is then signed and encapsulated within the outer SignedData object. As per [SMIME3], each layer is MIME encapsulated. This example depicts the CMS security services equivalent to a signed, encrypted and sequence-signed MSP security heading. The triple encapsulation depicted in Figure A4 could result from a user agent sending a signed and encrypted message to a Mail List Agent (MLA) which then adds the outer SignedData including the MLExpansionHistory attribute. Figure A4. MIME Encapsulation of CMS Signed/Encrypted/Signed Message A.4.1. MLA Sending Signed/Encrypted/Signed S/MIME Message This section provides an example of how a MLA could use the SFL to receive a signed/encrypted S/MIME message and then to relay it to the mail list as a signed/encrypted/signed S/MIME message. 1. MLA receives S/MIME message and parses outer MIME header. 2. MLA recognizes MIME content type as a CMS object. 3. MLA uses SFL to determine that the CMS object is a SignedData object. 4. MLA uses SFL to decode the SignedData object to determine the identity of the signer(s), algorithms used to sign the data, contentType of encapsulated data, etc. 5. MLA initializes the cryptographic token required to verify the SignedData (if not done already). 6. MLA obtains and validates signer's X.509 Certification path (could use freeware CM Library CM_RetrieveKey function). 7. MLA uses SM_Verify or CSM_VerifyMsg::Verify to validate the signature of the SignedData object. The SFL can be used to access all attributes, such as the eSSSecurityLabel, included in the verified SignedData. 8. MLA parses MIME header and recognizes content type as a CMS object. 9. MLA uses SFL to determine that the CMS object is an EnvelopedData object. 10. MLA uses SFL to decode the EnvelopedData object to determine the identity of the originator (if present), algorithms used to encrypt the data, contentType of encapsulated data, etc. 11. MLA initializes the cryptographic token required to decrypt the EnvelopedData (if not done already). 12. If required for the KM algorithm, the MLA obtains and validates originator’s X.509 Certification Path (could use freeware CM Library CM_RetrieveKey function). 13. MLA uses SM_Decrypt or CSM_DecryptMsg::Decrypt to decrypt the EnvelopedData content. 14. The MLA should continue parsing the MIME-encapsulated message to determine if there is a security label associated with an encapsulated CMS object. MLA parses decrypted MIME header and recognizes content type as CMS object. 15. MLA uses SFL to determine that the CMS object is a SignedData object. 16. MLA uses SFL to decode the SignedData object to determine the identity of the signer(s), algorithms used to sign the data, contentType of encapsulated data, etc. 17. MLA initializes the cryptographic token required to verify the SignedData (if not done already). 18. MLA obtains and validates signer's X.509 Certification path (could use freeware CM Library CM_RetrieveKey function). 19. MLA uses SM_Verify or CSM_VerifyMsg::Verify to validate the signature of the SignedData object. If a SignedData/Receipt is requested by the signer and the MLA has indicated that a SignedData/Receipt should be built (if requested), then the SFL generates it. The SFL can be used to access all attributes, such as the eSSSecurityLabel, included in the verified SignedData. 20. MLA parses MIME header and recognizes content type as original content, so it halts the process of parsing the nested security headings. 21. MLA retrieves and validates the X.509 Certification Path for each ML recipient (could use freeware CM Library CM_RetrieveKey function). 22. If required for the KM algorithm (e.g. KEA, DH), the MLA selects the ML’s private key material to be used as part of the process to encrypt the message. 23. MLA uses SM_Encrypt or CSM_EncryptMsg::Encrypt to produce the EnvelopedData object encapsulating the original MIME-encapsulated SignedData object 24. MLA encapsulates EnvelopedData in MIME header. 25. MLA selects private key material to be used to sign the data. 26. MLA fills in the data structures for the following attributes: ML Expansion History, content type. 27. MLA fills in the data structures for the optional attributes to be included in the SignedData object such as: security label; content description, etc. 28. MLA uses SM_Sign or CSM_SignMsg::Sign to produce the SignedData object encapsulating the MIME-encapsulated EnvelopedData object. 29. MLA encapsulates SignedData object in MIME header and sends. A.4.2. Receiving a Signed/Encrypted/Signed S/MIME Message 1. Application receives S/MIME message and parses outer MIME header. 2. Application recognizes MIME content type as a CMS object. 3. Application uses SFL to determine that the CMS object is a SignedData object. 4. Application uses SFL to decode the SignedData object to determine the identity of the signer(s), algorithms used to sign the data, contentType of encapsulated data, etc. 5. Application initializes the cryptographic token required to verify the SignedData (if not done already). 6. Application obtains and validates signer's X.509 Certification path (could use freeware CM Library CM_RetrieveKey function). 7. Application uses SM_Verify or CSM_VerifyMsg::Verify to validate the signature of the SignedData object. The SFL can be used to access all attributes, such as the eSSSecurityLabel, included in the verified SignedData. 8. Application parses MIME header and recognizes content type as a CMS object. 9. Application uses SFL to determine that the CMS object is an EnvelopedData object. 10. Application uses SFL to decode the EnvelopedData object to determine the identity of the originator (if present), algorithms used to encrypt the data, contentType of encapsulated data, etc. 11. Application initializes the cryptographic token required to decrypt the EnvelopedData (if not done already). 12. If required for the KM algorithm, the application obtains and validates originator’s X.509 Certification Path (could use freeware CM Library CM_RetrieveKey function). 13. Application uses SM_Decrypt or CSM_DecryptMsg::Decrypt to decrypt the EnvelopedData content. 14. Application parses decrypted MIME header and recognizes content type as a CMS object. 15. Application uses SFL to determine that the CMS object is a SignedData object. 16. Application uses SFL to decode the SignedData object to determine the identity of the signer(s), algorithms used to sign the data, contentType of encapsulated data, etc. 17. Application initializes the cryptographic token required to verify the SignedData (if not done already). 18. Application obtains and validates signer's X.509 Certification path (could use freeware CM Library CM_RetrieveKey function). 19. Application uses SM_Verify or CSM_VerifyMsg::Verify to validate the signature of the SignedData object. If a SignedData/Receipt is requested by the signer and the application has indicated that a SignedData/Receipt should be built (if requested), then the SFL generates it. (Note: If the ML Expansion History attribute was present in authenticatedAttributes of the outer SignedData object, then the application uses that information as part of the process described in [ESS] of deciding if the SignedData/Receipt created for the inner SignedData object should be sent and to whom it should be sent.) The SFL can be used to access all attributes, such as the eSSSecurityLabel, included in the verified SignedData. 20. Application parses MIME header and recognizes content type as original content. A.5. Other Types of Messages The aforementioned scenarios are just examples of how the CMS security services can be applied. Other combinations of security services are possible. For example, a SignedData object encapsulating another SignedData object would result when a user sends a signed-only message to an MLA because the MLA adds the outer SignedData including the MLExpansionHistory attribute. The CMS security services can be used to protect any type of data. Figure A5 depicts how an X.400/P772 message could be protected using CMS. This strategy could also be used to protect other forms of X.400 messages such as P2, P22, etc. This strategy could also be used to protect other data formats. Figure A5. Possible X.400 Encapsulation of CMS Signed/Encrypted/Signed P772 Message A.6. S/MIME Signed Receipt Figure A6 depicts the MIME Encapsulation of a CMS/ESS SignedData/Receipt. A CMS/ESS SignedData/Receipt is composed of a Receipt Content Type signed within a SignedData object. Note that there is not a MIME header encapsulating the Receipt Content Type within the SignedData object. The following section provides an example of how an application could use the SFL to validate an S/MIME SignedData/Receipt. Figure A6. MIME Encapsulation of CMS/ESS SignedData/Receipt A.6.1. Validating an S/MIME SignedData/Receipt 1. Application receives S/MIME message and parses outer MIME header. 2. Application recognizes content type as a CMS object. 3. Application uses SFL to determine that the CMS object is a SignedData object. 4. Application uses SFL to decode the SignedData object to determine: identity of the signer(s), algorithms used to sign the data, contentType indicates that a Receipt is encapsulated, etc. 5. Application initializes the cryptographic token required to verify the SignedData/Receipt (if not done already). 6. Application obtains and validates receipt signer's X.509 Certification path (could use freeware CM Library CM_RetrieveKey function). 7. Application uses the SFL to obtain the signedContentIdentifier included in the SignedData/Receipt to identify the original SignedData object that requested the SignedData/Receipt. 8. Application uses SM_ValReceipt or CSM_VerifyReceiptMsg::Verify to validate the signature of the SignedData/Receipt object. 9. Application takes appropriate action based on result of SM_ValReceipt processing. V0.2 DRAFT SFL API iv V0.1 DRAFT SFL SDD 16