Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_CardSpace Component Proposal

Proposed Component Name Zend_CardSpace
Developer Notes
Proposers John Coggeshall
Revision 1.0-draft - 30 August 2007: Initial Draft (wiki revision: 11)

Table of Contents

1. Overview

Zend_CardSpace is an implementation of the Microsoft CardSpace authentication mechanism which enables web sites to validate CardSpace authentication tokens submitted to the web site.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

The Zend_CardSpace component is designed to process CardSpace tokens provided to it (likely from an HTTP Post) and achieve the following goals

  • Decryption of the token using the rules of CardSpace
  • Validation of the signature of the token
  • Retrieval of the claims within a token to the calling application

To accomplish this task a series of classes must be created to encapsulate the various XML block elements contained within a CardSpace token and then use these building blocks to follow the linear decryption and validation process established to retrieve the claims contained within it. Specifically the CardSpace component's requirements are as follows:

  • This component will parse a properly formatted CardSpace token into a custom object hierarchy based on the XML structure of the token
  • This component will use the aforementioned hierarchy to perform the decryption process to extract the encrypted Claims/Assertions
  • This component will validate the encrypted Signed token using public key encryption mechanisms described in by the CardSpace specification to validate the authenticity of the claims made within it
  • This component will be extendable in every way necessary allowing for new cryptographic methods, token formats, etc. to emerge to be later introduced into the component
  • This component will not support (initially) any symmetric encryption algorithm other then AES-256 with CBC for the purposes of decrypting the transient key
  • This component will not support (initially) any public key encryption algorithm other then RAS-OAEP-MGF1P
  • This component will not support (initially) any XML canonicalization method other then XML-C14N for the purposes of validating a Signed Token
  • This component will not support (initially) any public key digest / fingerprint algorithm other then SHA1
  • This component will not support (initially) any data encoding format other then Base64
  • This component will support RSA keys represented in both modulus/exponent and X509 Certificate formats
  • This component will not save any data using Zend_Cache or other data storage. It is the responsibility of the larger application to provide to the component a temporary storage mechanism if desired for the purposes of storing previously processed token identifiers
  • This component will interoperability with the Zend_Auth component, although the component does not require using it in that fashion
  • This component will be able to be used independently from Zend Framework and will be distrobuted as both a Framework Component and independent library

4. Dependencies on Other Framework Components

  • Zend_Exception (when used in Zend Framework, the component will support the Internal Exception class as well if used independently)
  • Zend_Auth (not really a dependency, will provide an authentication wrapper class for use within Framework)
  • openssl extension
  • mcrypt extension
  • simplexml extension
  • dom extension

5. Theory of Operation

Need to Know Terms
The follow definitions are necessary to accurately interpret this document:

  • Relying Party: The web site which requires a user to present a CardSpace Information Card in order to use all or part of the site.
  • Claims: Information required by the Relying Party and provided by the End user in the form of an identity card. Such as Name, E-mail Address, Phone Number, etc. In CardSpace claims are considered key/value pairs.
  • Identity Provider: A third party entity which is trusted by the Relying Party which can issue Information Cards to users which can be used at CardSpace-enabled web sites. When presented with such an Information Card by an end user, the Relying Party must validate the information contained within the card with the issuing Identity Provider.
  • SAML: An abbreviation for Security Assertion Markup Language, an XML-based format for relaying security assertion information. (See:
  • Encrypted (SAML) Token: An encrypted Token is the data sent by the end user to the relying party and it represents the end user's Information Card. For the purposes of this document we will assume this token is a XML document formatted to the Security Assertion Markup Language (SAML) specification. While we will assume SAML, the architecture must support the possible addition of new token formats without significant alterations to the code base.
  • Signed Token: For the purposes of this document, a Signed Token is contained within an Encrypted token. It is a public-keyset encrypted piece of data which contains the claims of the end user that must be validated by the CardSpace component

Operational Flow
On a high level, the ultimate goal of the CardSpace component is to accept as input an Encrypted Token and provide as output the claims contained within in. However, in order to accomplish its goal of validation and security many intermediate steps exist and are encapsulated within the CardSpace Component. These steps are outlined as follows:

1. Notification of CardSpace support
2. Receiving of an Encrypted Token by the End User
3. Parsing of the Encrypted Token
4. Decryption of the Encrypted Token to retrieve the Signed Token
5. Validation of the Signed Token
6. Parsing of the Claims within the Signed Token
7. Creation of a data storage object containing the validated claims within the Signed Token

In this document we will focus only on those items listed in bold, the functionality provided by the CardSpace component.

Parsing of the Encrypted Token
The Encrypted Token is the container within which the claims (contained within a Signed Token) are transmitted to the Relying Party in such a way that only the Relying Party can decrypt the data. Contained within this XML document is all of the information needed to retrieve the claims of the end user when combined with the private keys of both the relying party and the identity provider. For this first step however, only the following steps are necessary:

1. Determine the symmetric encryption algorithm used to encrypt the Signed Token
2. Retrieve the encrypted transient key used to encrypt the signed token

In order to understand the significance of these steps you must understand the process used to generate this portion of the Encrypted Token. When an Encrypted Token is created, the Signed Token is encrypted using a symmetric encryption algorithm to protect it using a randomly-generated encryption key. Since the Relying Party has no means of knowing what that random key is, it is provided as part of the Encrypted Token. This random key, called a transient key, must also be encrypted to ensure only the Relying party will be able to decrypt the Encrypted Token and gain access to the Signed Token. To accomplish this, the transient key is encrypted using the public key of the relying party (taken from their SSL certificate) and placed into the Encrypted Token in its public-key encrypted form.

Below is an example Encrypted Token with comments in place of encryption-related values for your reference:

From an implementation perspective the following tasks must occur for this step when provided with an Encrypted Token.
1. Determine the Symmetric encryption algorithm used (currently only AES-256 with CBC supported). This algorithm is found in the Algorithm attribute of the <enc:EncryptionMethod> element.
2. Retrieve the encryption method used to encrypt the transient key (currently only RSA-OAEP-MGF1P algorithm and encoding supported). The encryption method can be found in the Algorithm attribute of the <enc:EncryptionMethod> element.
3. Determination of the Private key used to decrypt the Symmetric key by comparing the fingerprint values using the hash algorithm specified in the ValueType attribute of the <o:KeyIdentifier> element. Note that currently only SHA1 Thumbprint hashes are supported with Base64 encoding (specified in the EncodingType attribute of the same element).
4. Retrieve the encrypted symmetric key from the <e:CiperValue> element.

With these tasks implemented, you are ready to move on to the next step - retrieval of the Signed Token through decryption of the Encrypted Token's symmetric encryption

Retrieval and Decryption of the Signed Token

Once you have determined the method of encryption of the Signed Token as well as the method of encryption of the transient key, the server now has everything it will need in order to decrypt the Signed Token contained within the Encrypted Token. Specifically the following steps must occur:

1 Decryption of the Transient Key using the Relying Party's Private Key
2.Decryption of the Signed Token using the Transient Key

While appearing straightforward, there are complexities to this step which must be accounted for. Specifically due to potential foreseen limitations of PHP to cleanly handle public/private key encryption in the way desired, there may be a need to ultimately patch PHP (please bring the issue up with John Coggeshall) and temporary file based workaround for previous versions of PHP 5. Specifically the development must use two non-standard PHP extensions: openssl (for private key decryption), and mcrypt (for AES256-CBC decryption).

Note: Future plans for Zend Framework call for the implementation of some of these algorithms natively within PHP as part of a proposed Zend_Crypt extension. Initially this component must check for the existence of required extensions, however if available in the future the component should be modified to fall back to the Zend_Crypt component for support in this area if the native extensions are unavailable.

From an implementation perspective the following issues should be accounted for in the retrieval of the Signed Token:

1. While when extracting the information used in this step from the Encrypted Token the encryption types should have already been verified as supported, during encryption this check should take place again as a preventive measure.
2. For AES256-CBC the MCRYPT_RIJNDAEL_128 cipher should be used using the MCRYPT_MODE_CBC mode (The IV length is 16)
3. The encryption code should be written to allow easy extensibility (new encryption schemes) and future fallback to non-extension implementations of the encryption algorithms (Zend_Crypt)

Validation of the Signed Token
Signed Tokens can be in many different formats, however for the purposes of this architecture only the SAML variety will be supported (although room should be kept to allow new token formats to be implemented). An example token is shown below:

When validating a Signed Token there are a number of steps that must be taken listed below:
1. Verification of originality of Token by using the data highlighted in blue to assure the token is valid and within the correct time window.
2. Determine the Canonicalization method to be applied to the XML document and the digest method used to generate the document digest.
3. Convert the Signed Token to its Canonical form using the algorithm specified in the Signed Token and compare the digest to the one provided
4. Determine the Signature Method used on the Signed Token and apply it to validate the source of the Token

Validation of the Signed Token is by far the most complex and prone-to-error aspect of the development of the CardSpace component. In the following sections we will examine each step and provide details regarding the implementation of each in practical terms.

Verification of originality of Token
The first step when provided a Signed token is to validate that the token is legitimate and been submitted within acceptable parameters according to the Token itself. This task is done by checking the following:

1. The token was provided within an acceptable window of time (not prior or after the NotBefore and NotAfter attributes of the <saml:Conditions> element)
a. Times are provided using Coordinated Universal Time (UTC) and the Relying Party should translate the local time into this format before comparing
b. A "reasonable" delta must be applied to time validation to ensure differences between the server time / Identity Provider time do not cause incorrect operation
2. In regards to the <saml:Assertion> element the following are true
a. The Issuer attribute is a valid, acceptable issuer
b. The AssertionID attribute is unique identifier

Note: Regarding the Assertion ID, it is critical from a security perspective that the same Assertion ID is not provided twice for the length of time specified in the <saml:Conditions> element. Because the component being designed has no internal storage mechanism for such data, the component must provide a mechanism to allow the end developer using the component to provide a storage container for this data to be used by the Component. If no such container is provided this validation step is not performed.

Determining the Canonicalization method
For the purposes of validating the Signed Token, it is absolutely imperative that that signature used for comparison is calculated from the exact same document the Identity Provider used to calculate the signature when the token was constructed. Unless the document is identical, the signature validation will fail. To facilitate this critical step the document must be converted into a canonical version of the token according to the algorithm specified in the Algorithm attribute of the CanonicalizationMethod element the XML above. For the purposes of this architecture only XML-C14N canonicalization will be supported (although room for additional canonicalization methods should be provided).

Once the document canonicalization method has been determined the digest method must also be established. This can be determined by the Algorithm attribute of the <DigestMethod> element in the XML above. For the purposes of this architecture the SHA1 is the only supported method (although additional digest methods should be allowed).

Validating the Signed Token Digest
Once the Canonicalization algorithm has been established the Signed Token (minus the <Signature> element) must be have this algorithm applied to it to convert the document into this standardized form. The digest determined in the previous step is then applied to this canonical form of the Signed Token and compared to the digest value provided by the Signed Token to validate the data's integrity.

Note: The digest value provided is base64 encoded. It is recommended a comparison of the digest in its base64 encoded version be used.

From an implementation standpoint the transformations which must take place are outlined in the <Transforms> XML element and show be applied in reverse (FIFO) order against the Signed Token without the <Signature> block included.

Validate the Signature of the Signed Token
With the contents of the token verified by the previous step, the final step in the validation of the Signed Token (and thus validation of the claims) is the validation of the signature contained within the Signed token itself. The first step in this process is the determination of the public key encryption method used to sign the document which can be found in the Algorithm attribute of the <SignatureMethod> element in the XML above.

With the encryption method determined the Signed Token is ready to be validated as authentic by comparing the Signature provided in the token (which was created by the Identity Provider and creator of the Signed Token using their private key) against the public key provided within the Signed Token to ensure the full contents of the token are authentic. This process can be broken down into the following steps:

1. Retrieve the public key of the creator of the Signed Token. The public key can be provided in one of two supported methods - as a Raw RSA key or X509 certificate. Which method to be used can be determined by the available representations of the public key in the Signed Token found under the <KeyValue> element in the XML above. Possible elements which are supported under the specified <KeyValue> element are as follows:
a. <RSAKeyValue>: A raw RSA key which contains two sub-elements <Modulus> and <Exponent>
b. <X509Certificate>: The certificate value. In a PHP implementation this certificate must be converted into PEM encoding before providing it to the OpenSSL extension
2. Validation of the reference URI which indicates what the signature is intended for by comparing the URI attribute of the <Reference> element to the AssertionID attribute of the <saml:Assertion> element
3. Application of all of the Transformations described in the <Transforms> element to the <SignedInfo> and included elements.
4. Verification of public key against the Transformed <SignedInfo> element block and the signature value provided in the <SignatureValue> element (base64 encoded)

Ultimately, after these four steps are completed successfully it is now verified cryptographically that the Signed Token provided indeed comes from the source provided. From this point we must provide the claims contained within the Signed Token back to the user as the requested data by returning a Zend_CardSpace_Claims object based on the <Assertions> block of the XML Document

6. Milestones / Tasks

  • Milestone 1: [DONE] Proposal Creation
  • Milestone 2: Creation of XML Processing objects needed to process an <EncryptedData> element complete
  • Milestone 3: Creation of necessary encryption objects needed to decrypt an <EncryptedData element complete
  • Milestone 4: Creation of XML Processing objects needed to process a <SignedToken> element complete (minus Assertions)
  • Milestone 5: Creation of necessary encryption objects needed to decrypt a <SignedToken> element complete
  • Milestone 6: Creation of Transformation objects needed to transform a <SignedToken> element complete
  • Milestone 7: Creation of XML Processing objects for Assertions and Zend_CardSpace_Claims complete
  • Milestone 8: Creation of Zend_CardSpace wrapper to perform the decryption/validation process complete

7. Class Index

  • Zend_CardSpace_Xml_Element_Interface
  • Zend_CardSpace_Xml_Element
  • Zend_CardSpace_Xml_EncryptedData_Abstract
  • Zend_CardSpace_Xml_EncryptedData_XmlEnc
  • Zend_CardSpace_Xml_EncryptionMethod
  • Zend_CardSpace_Xml_KeyInfo
  • Zend_CardSpace_Xml_KeyInfo_Default
  • Zend_CardSpace_Xml_KeyInfo_XmlDSig
  • Zend_CardSpace_Xml_KeyInfo_Interface
  • Zend_CardSpace_Xml_Cipher_Data
  • Zend_CardSpace_Xml_Cipher_Data_Reference
  • Zend_CardSpace_Xml_Transform_Abstract
  • Zend_CardSpace_Xml_Transform_XmlExcC14n
  • Zend_CardSpace_Xml_Transform_Chain
  • Zend_CardSpace_Xml_Signature
  • Zend_CardSpace_Xml_SignedInfo
  • Zend_CardSpace_Xml_Reference
  • Zend_CardSpace_Exception
  • Zend_CardSpace_Xml_Exception
  • Zend_CardSpace_Claims
  • Zend_CardSpace
  • Zend_CardSpace_Auth_Adapter
  • Zend_CardSpace_Auth_Result

8. Use Cases


9. Class Skeletons



zend_cardspace zend_cardspace Delete
cardspace cardspace Delete
zend_auth zend_auth Delete
authentication authentication Delete
claims claims Delete
proposal proposal Delete
proposals proposals Delete
microsoft microsoft Delete
identity identity Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Aug 31, 2007

    <p>Will the user ever use or come into contact with Zend_CardSpace_Xml_* classes?</p>

    1. Sep 07, 2007

      <p>Nope, as shown in the use-cases there isn't any need to. They are just used internally to represent the different XML blocks. The benefit to this approach is that from a testing perspective unit-tests can be develped against the proper parsing of each individual element block to make sure things work as-expected.</p>

  2. Sep 14, 2007

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Comments</ac:parameter><ac:rich-text-body>
    <p>This proposal has been approved for incubator development.</p></ac:rich-text-body></ac:macro>