Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / Recipient.cs / 2 / Recipient.cs
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.InfoCards
{
using System;
using System.IO;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.ServiceModel.Security.Tokens;
using Microsoft.InfoCards.Diagnostics;
using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace;
using System.IdentityModel.Tokens;
using System.IdentityModel.Selectors;
using System.Globalization;
using System.ComponentModel;
using System.Runtime.InteropServices;
internal class Recipient
{
public enum TrustDecision : byte
{
NoTrustDecision, // Indicating a recipient for whom a trust decision has never been made before
IsTrusted, // Indicating a recipient who has been trusted before
IsNotTrusted, // Indicating a recipient who has been set to "untrusted" before
PolicyVersionChange
};
public enum IdentityType : byte
{
DNS = 0,
X509 = 1
};
enum IdType : byte
{
RecipientId = 0,
OrganizationId = 1,
PPIDSeed = 2
};
public struct RecipientCertParameters
{
//
// This structure is used to conveniently pass around
// and update all these parameters in a method/function call.
//
public string m_cn;
public string m_organization;
public string m_locality;
public string m_state;
public string m_country;
public Utility.SubjectAtrributeHAFlags m_certHAFlags;
public RecipientCertParameters(
string cn,
string organization,
string locality,
string state, /* SSS_WARNINGS_OFF */
string country,
Utility.SubjectAtrributeHAFlags certHAFlags
) /* SSS_WARNINGS_ON */
{
m_cn = cn;
m_organization = organization;
m_locality = locality;
m_state = state; /* SSS_WARNINGS_OFF */
m_country = country; /* SSS_WARNINGS_ON */
m_certHAFlags = certHAFlags;
}
};
const Int32 InvalidRow = 0;
const byte Version = 1;
const byte m_marker = 29;
// Geographic attribute types:
public const int CERT_NAME_ATTR_TYPE = 3;
public const string szOID_SUBJECT_CN = "2.5.4.3"; // case-ignore string
public const string szOID_ORGANIZATION_NAME = "2.5.4.10"; // case-ignore string
public const string szOID_LOCALITY_NAME = "2.5.4.7"; // case-ignore string
public const string szOID_STATE_OR_PROVINCE_NAME = "2.5.4.8"; // case-ignore string /* SSS_WARNINGS_OFF */
public const string szOID_COUNTRY_NAME = "2.5.4.6"; // printable 2char string
const int attributeMaxLength = 1024;
static readonly RecipientAttribute CNAttr = new RecipientAttribute( szOID_SUBJECT_CN, "CN" );
static readonly RecipientAttribute OrgAttr = new RecipientAttribute( szOID_ORGANIZATION_NAME, "O" );
static readonly RecipientAttribute LocalityAttr = new RecipientAttribute( szOID_LOCALITY_NAME, "L" );
static readonly RecipientAttribute StateOrProvinceAttr = new RecipientAttribute( szOID_STATE_OR_PROVINCE_NAME, "S" );
static readonly RecipientAttribute CountryAttr = new RecipientAttribute( szOID_COUNTRY_NAME, "C" ); /* SSS_WARNINGS_ON */
struct RecipientAttribute
{
string m_name;
string m_delimitingString;
public RecipientAttribute(string name, string delimitingString)
{
m_name = name;
m_delimitingString = delimitingString;
}
public string DelimitingString
{
get { return m_delimitingString; }
}
public string Name
{
get { return m_name; }
}
}
//
// This ID is unique to every site
// Used to index into the ledger entries.
// I.e. one recipient ID --> one ledger entry
//
string m_recipientId;
//
// This ID is shared between different sites from the same organization.
// Used to generate PPID & the pair-wise asymmetric key.
//
string m_recipientOrganizationId;
string m_issuerName;
string m_subjectName;
uint m_privacyNoticeVersion;
IdentityType m_type = IdentityType.DNS;
TrustDecision m_trustDecision;
//
// Recipient Cert parameters - initial to empty values.
// This will be set only if we initialize with a cert.
//
RecipientCertParameters m_recipientParams
= new RecipientCertParameters(
"",
"",
"",
"",
"",
Utility.SubjectAtrributeHAFlags.NotEnabled );
//
// Indicates whether the recipients cert is cached on the client request or not.
//
bool m_isCertCached;
Int32 m_rowId = InvalidRow;
byte[] m_publicKey;
List m_logoMetadata;
//
// Used by GetRecipientListRequest, LedgerEntry - simply needs to read a Recipient object from the store
//
public Recipient(Stream stream) : this( stream, false ) { }
//
// Used by GetPolicyDetailsRequest - which needs to get logo information for an incoming cert
//
public Recipient(Stream stream, RecipientIdentity identity, bool isCertCached)
: this( stream, isCertCached )
{
X509RecipientIdentity x509Id = identity as X509RecipientIdentity;
if( null != x509Id )
{
m_type = IdentityType.X509;
AddLogoMetadata( x509Id.LeafCertificate );
//
// Use the recipient parameters from the incoming policy
//
m_recipientParams = x509Id.RecipientParams;
}
}
//
// Gate constructor for the above
//
private Recipient(Stream stream, bool isCertCached)
{
m_isCertCached = isCertCached;
Deserialize( stream );
}
//
// Summary:
// Recipient constructor - used to construct new recipients as opposed to deserializing from the store
//
// Params:
// recipientId - recipient identifier
// isCertCached - flag reflecting if cert is cached or not
// privacyNoticeVersion - privacy notice version
//
//
//
public Recipient(
RecipientIdentity identity,
bool isCertCached,
uint privacyNoticeVersion)
{
m_trustDecision = TrustDecision.NoTrustDecision;
m_isCertCached = isCertCached;
m_privacyNoticeVersion = privacyNoticeVersion;
m_recipientId = identity.GetIdentifier();
m_recipientOrganizationId = identity.GetOrganizationIdentifier();
m_subjectName = identity.GetName();
X509RecipientIdentity x509Id = identity as X509RecipientIdentity;
if( null != x509Id )
{
m_type = IdentityType.X509;
m_issuerName = x509Id.LeafCertificate.GetNameInfo( X509NameType.SimpleName, true );
m_recipientParams = x509Id.RecipientParams;
m_publicKey = x509Id.LeafCertificate.GetPublicKey();
AddLogoMetadata( x509Id.LeafCertificate );
}
}
//
// Summary:
// Recipient constructor - used to construct new recipients as opposed to deserializing from the store
//
// Params:
// cert - the recipient cert
// recipientId - recipient identifier
// recipientOrgId - recipient identifier for the organization
// isCertCached - flag reflecting if cert is cached or not
// privacyNoticeVersion - privacy notice version
// RecipientCertParameters - Other useful fields from the certificate
//
// Remarks:
// We could have easily calculated the recipientId from the cert,
// but we pass it in becuase in the normal flow it is already populated in the InfoCardPolicy object.
// Especially, on some incoming agent requests we need the recipient identifer even before the
// recipient object is created (to do lookups in the store).
//
//
// Used by GetTokenRequest & RemoteTokenFactory [to create and save a recipient]
//
public Recipient(
X509Certificate2 cert,
string recipientId,
string recipientOrgId,
bool isCertCached,
uint privacyNoticeVersion,
RecipientCertParameters recipientParameters)
{
m_type = IdentityType.X509;
m_trustDecision = TrustDecision.NoTrustDecision;
m_publicKey = cert.GetPublicKey();
m_isCertCached = isCertCached;
m_privacyNoticeVersion = privacyNoticeVersion;
m_subjectName = cert.FriendlyName;
if( string.IsNullOrEmpty( m_subjectName ) )
{
m_subjectName = cert.GetNameInfo( X509NameType.SimpleName, false );
}
m_issuerName = cert.GetNameInfo( X509NameType.SimpleName, true );
m_recipientId = recipientId;
m_recipientOrganizationId = recipientOrgId;
m_recipientParams = recipientParameters;
AddLogoMetadata( cert );
}
public string RecipientId
{
get
{
IDT.Assert( !String.IsNullOrEmpty( m_recipientId ), "Must be populated before this property is accessed" );
return m_recipientId;
}
}
public RecipientCertParameters RecipientParameters
{
get
{
return m_recipientParams;
}
}
public uint PrivacyPolicyVersion
{
get { return m_privacyNoticeVersion; }
set { m_privacyNoticeVersion = value; }
}
//
// Summary:
// Get the O L S C attributes out of the subject of the cert and construct the string per the
// RP Identifier DCR.
//
// Arguments:
// recipientCert - the cert belinging to the recipient
// supportingRecipientCerts - intermediate certs that may be needed for chain building
// (if they are not already on the box)
// idtype - the type of id that is requested
// recipientParams - Output struct containing other useful cert fields.
//
// Remarks:
// 1) If O, L, S, C are empty strings, returns the public key
// 2) Example: Assume there are 2 faces to an organization, whose chain is trusted by user.
// Suppose Face1.cer and Face2.cer have the same OLSC.
// Suppose user visits Face1.com and submits a card.
// Now user goes to Face2.com.
// We will show the RIP page for Face2.com. However to allow co-relation of user
// at the organization end, we will send the same pair-wise asymmetric key
// and PPID etc.
// And note the above is true whether or not it is HA cert case.
// 3) If O, L, S, C are not empty the following rules apply
// HA case:
// RPID case example:
// |CN=\"InfocardBvtHaFace1\"|O=\"IENetTest\"|L=\"Redmond\"|S=\"Washington\"|C=\"US\"|"
//
// ORGID case example:
// |O=\"IENetTest\"|L=\"Redmond\"|S=\"Washington\"|C=\"US\"|"
//
// ORGPPID case example:
// |O=\"IENetTest\"|L=\"Redmond\"|S=\"Washington\"|C=\"US\"|"
//
//
// For the Non-HA case:
//
// RPID case example:
// "|ChainElement=\"C=US, S=Washington, L=Redmond, O=CA2, E=zws@yahoo.com, CN=Root2\"
// |ChainElement=\"C=US, S=Washington, L=Redmond, O=CA2, CN=CA2\"
// |CN=\"END2\"|O=\"IENetTest\"|L=\"Redmond\"|S=\"Washington\"|C=\"US\"|"
//
// ORGID case example:
// |Non-EV|O=\"IENetTest\"|L=\"Redmond\"|S=\"Washington\"|C=\"US\"|"
//
// ORGPPID case example:
// |O=\"IENetTest\"|L=\"Redmond\"|S=\"Washington\"|C=\"US\"|"
//
static byte[] CertGetRecipientIdBytesForChainTrust(
X509Certificate2 recipientCert,
X509Certificate2Collection supportingRecipientCerts,
IdType idtype,
out RecipientCertParameters recipientParams )
{
recipientParams = new RecipientCertParameters(
"",
"",
"",
"",
"",
Utility.SubjectAtrributeHAFlags.NotEnabled );
//
// Case 2 OR Case 3
//
string recipientIdString = "";
//
// Lets get the OLSC string first
//
string org = GetCertAttribute( OrgAttr.Name, recipientCert.Handle );
string locality = GetCertAttribute( LocalityAttr.Name, recipientCert.Handle );
string stateOrProvince = GetCertAttribute( StateOrProvinceAttr.Name, recipientCert.Handle ); /* SSS_WARNINGS_OFF */
string country = GetCertAttribute( CountryAttr.Name, recipientCert.Handle );
recipientParams.m_cn = GetCertAttribute(CNAttr.Name, recipientCert.Handle); ;
recipientParams.m_organization = org;
recipientParams.m_locality = locality;
recipientParams.m_state = stateOrProvince;
recipientParams.m_country = country;
if( String.IsNullOrEmpty( org ) )
{
//
// Means it is not a org, more a personal cert. So use cn
// even though it chains up to a trusted CA.
//
if( !String.IsNullOrEmpty( recipientParams.m_cn ) )
{
String cn = String.Format(
CultureInfo.InvariantCulture,
"|{0}=\"{1}\"|",
CNAttr.DelimitingString, recipientParams.m_cn );
return Encoding.Unicode.GetBytes( cn );
}
else
{
return recipientCert.GetPublicKey();
}
}
//
// String.Format uses the StringBuilder to build the string and the StringBuilder buffers the string
// for performance.
//
//
// IMPORTANT: Includes CN if !getOrganizationId
//
string geographicalAttributes;
if( IdType.OrganizationId == idtype || IdType.PPIDSeed == idtype )
{
//
// Only use the OLSC fields
// Example geographicalAttributes = "|O=\"InfoCardBvtOrg\"|L=\"Redmond\"|S=\"Washington\"|C=\"US\"|"
//
geographicalAttributes = String.Format(
CultureInfo.InvariantCulture,
"|{0}=\"{1}\"|{2}=\"{3}\"|{4}=\"{5}\"|{6}=\"{7}\"|",
OrgAttr.DelimitingString, org,
LocalityAttr.DelimitingString, locality,
StateOrProvinceAttr.DelimitingString, stateOrProvince,
CountryAttr.DelimitingString, country );
}
else
{
//
// Use the cert CN as well
// Example geographicalAttributes = "|CN=\"InfocardBvtHaFace1\"|O=\"InfoCardBvtOrg\"|L=\"Redmond\"|S=\"Washington\"|C=\"US\"|"
//
geographicalAttributes = String.Format(
CultureInfo.InvariantCulture,
"|{0}=\"{1}\"|{2}=\"{3}\"|{4}=\"{5}\"|{6}=\"{7}\"|{8}=\"{9}\"|",
CNAttr.DelimitingString, recipientParams.m_cn,
OrgAttr.DelimitingString, org,
LocalityAttr.DelimitingString, locality,
StateOrProvinceAttr.DelimitingString, stateOrProvince,
CountryAttr.DelimitingString, country );
}
Utility.SubjectAtrributeHAFlags certHAFlags = Utility.SubjectAtrributeHAFlags.NotEnabled;
bool isCertHA = Utility.GetCertHAFlags(
recipientCert,
supportingRecipientCerts,
ref certHAFlags );
//
// Lets construct the remainder
//
if( isCertHA )
{
//
// Case 2: If high assurance, no need to build chain
// Get the 4 components - O, L, S, C.
// Per Kelvin Yui, with either all are HA or they are not.
//
recipientParams.m_certHAFlags = certHAFlags;
if( Utility.IsSubjectAtrributeHAFlagsSet( certHAFlags, Utility.SubjectAtrributeHAFlags.LocStateCountryHA ) ^
Utility.IsSubjectAtrributeHAFlagsSet( certHAFlags, Utility.SubjectAtrributeHAFlags.OrganizationHA ) )
{
IDT.TraceDebug( "Unexpected but non-fatal: Both LocStateCountry & Organization must be high assurance together" );
}
//
// NB: For the !getOrganizationId case we already added the CN above.
//
recipientIdString = geographicalAttributes;
//
// Not legal to flag a certificate with the HA bits if O, L, S, and C are not defined.
//
if( String.IsNullOrEmpty( recipientIdString ) )
{
throw IDT.ThrowHelperError(
new UntrustedRecipientException(
SR.GetString( SR.InvalidHACertificateStructure ) ) );
}
} /* SSS_WARNINGS_ON */
else
{
//
// Case 3: Else build the chain
//
X509Chain chain;
//
// Will throw if validation fails, which is fine.
// Note the work to do chain.Build is the same as trying to validate it.
//
try
{
InfoCardX509Validator.ValidateChain( recipientCert, supportingRecipientCerts, out chain );
}
catch( SecurityTokenValidationException ex )
{
//
// Extrememly unlikely since validation to trusted root CA has passed at this point.
// Nonetheless, if there is failure, treat is as a untrusted recipient.
//
throw IDT.ThrowHelperError(
new UntrustedRecipientException(
SR.GetString( SR.UnableToBuildChainForNonHARecipient ), ex ) );
}
//
// Only for OrganizationId add a "Non-EV" flag
//
if ( IdType.OrganizationId == idtype )
{
recipientIdString = "|Non-EV";
}
//
// Only for a recipientId add the chain elements
//
if( IdType.RecipientId == idtype )
{
//
// Exclude the leaf (the cert we're processing, which is first in the list), include the rest
//
for( int i = 1; i < chain.ChainElements.Count; i++ )
{
X509ChainElement ele = chain.ChainElements[ i ];
recipientIdString = String.Format(
CultureInfo.InvariantCulture,
"|ChainElement=\"{0}\"{1}",
ele.Certificate.Subject, recipientIdString );
}
}
recipientIdString = recipientIdString + geographicalAttributes;
}
//
// Get and return unicode bytes
//
return Encoding.Unicode.GetBytes( recipientIdString );
}
//
// Summary:
// Returns Organization PPID seed based on isChainTrusted:
//
// Arguments:
// recipientCert - the cert belonging to the recipient
// supportingRecipientCerts - intermediate certs that may be needed for chain building
// (if they are not already on the box)
// isChainTrusted - indicates if the cert passed chain trust validation
//
//
// Return Value:
// the RP organization PPID seed for the recipient.
//
//
public static string CertGetRecipientOrganizationPPIDSeedHash(
X509Certificate2 recipientCert,
X509Certificate2Collection supportingRecipientCerts,
bool isChainTrusted)
{
byte[] recipientIdentity;
if( !isChainTrusted )
{
//
// Case 1 - simply use public key
//
recipientIdentity = recipientCert.GetPublicKey();
}
else
{
//
// Case 2 OR Case 3
//
Recipient.RecipientCertParameters parameters;
recipientIdentity = CertGetRecipientIdBytesForChainTrust(
recipientCert,
supportingRecipientCerts,
IdType.PPIDSeed,
out parameters );
}
//
// 1) Take a SHA256 hash of the bytes, hash gets 32 bytes
// 2) Convert to base 64. (compression will be 3->4 === 32 bytes -> 44 bytes)
//
byte[] theBytes;
using( SHA256 sha256 = new SHA256Managed() )
{
theBytes = sha256.ComputeHash( recipientIdentity );
}
return Convert.ToBase64String( theBytes );
}
//
// Summary:
// Returns Organization RecipientId based on isChainTrusted:
// Chain not trusted - Case 1 of RP Identifier DCR
// Chain trusted - Case 2 or 3 of RP Identifier DCR
//
//
// Arguments:
// recipientCert - the cert belinging to the recipient
// supportingRecipientCerts - intermediate certs that may be needed for chain building
// (if they are not already on the box)
// isChainTrusted - indicates if the cert passed chain trust validation
//
//
// Return Value:
// the RP organization identifier for the recipient.
//
//
public static string CertGetRecipientOrganizationIdHash(
X509Certificate2 recipientCert,
X509Certificate2Collection supportingRecipientCerts,
bool isChainTrusted )
{
byte[] recipientIdentity;
if( !isChainTrusted )
{
//
// Case 1 - simply use public key
//
recipientIdentity = recipientCert.GetPublicKey();
}
else
{
//
// Case 2 OR Case 3
//
Recipient.RecipientCertParameters parameters;
recipientIdentity = CertGetRecipientIdBytesForChainTrust(
recipientCert,
supportingRecipientCerts,
IdType.OrganizationId,
out parameters );
}
//
// 1) Take a SHA256 hash of the bytes, hash gets 32 bytes
// 2) Convert to base 64. (compression will be 3->4 === 32 bytes -> 44 bytes)
//
byte[] theBytes;
using( SHA256 sha256 = new SHA256Managed() )
{
theBytes = sha256.ComputeHash( recipientIdentity );
}
return Convert.ToBase64String( theBytes );
}
//
// Summary:
// Returns RecipientId based on isChainTrusted:
// Chain not trusted - Case 1 of RP Identifier DCR
// Chain trusted - Case 2 or 3 of RP Identifier DCR
//
//
// Arguments:
// recipientCert - the cert belinging to the recipient
// supportingRecipientCerts - intermediate certs that may be needed for chain building
// (if they are not already on the box)
// isChainTrusted - indicates if the cert passed chain trust validation
// recipientParams - Output useful set of cert parameters used by UI.
//
//
// Return Value:
// the RP identifier for the recipient.
// recipieintParams are not set for non trusted certs.
//
//
public static string CertGetRecipientIdHash(
X509Certificate2 recipientCert,
X509Certificate2Collection supportingRecipientCerts,
bool isChainTrusted,
out RecipientCertParameters recipientParams)
{
byte[] recipientIdentity;
if( !isChainTrusted )
{
//
// Case 1 - simply use public key
//
recipientIdentity = recipientCert.GetPublicKey();
recipientParams = new RecipientCertParameters(
GetCertAttribute( CNAttr.Name, recipientCert.Handle ),
GetCertAttribute( OrgAttr.Name, recipientCert.Handle ),
GetCertAttribute( LocalityAttr.Name, recipientCert.Handle ),
GetCertAttribute( StateOrProvinceAttr.Name, recipientCert.Handle ), /* SSS_WARNINGS_OFF */
GetCertAttribute( CountryAttr.Name, recipientCert.Handle ), /* SSS_WARNINGS_ON */
Utility.SubjectAtrributeHAFlags.NotEnabled );
}
else
{
//
// Case 2 OR Case 3
//
recipientIdentity = CertGetRecipientIdBytesForChainTrust(
recipientCert,
supportingRecipientCerts,
IdType.RecipientId,
out recipientParams );
}
//
// 1) Take a SHA256 hash of the bytes, hash gets 32 bytes
// 2) Convert to base 64. (compression will be 3->4 === 32 bytes -> 44 bytes)
//
byte[] theBytes;
using( SHA256 sha256 = new SHA256Managed() )
{
theBytes = sha256.ComputeHash( recipientIdentity );
}
return Convert.ToBase64String( theBytes );
}
private static string GetCertAttribute(string geographicAttributeName, IntPtr certHandle)
{
StringBuilder pszNameString = new StringBuilder( attributeMaxLength );
int retVal = NativeMethods.CertGetNameString(
certHandle,
CERT_NAME_ATTR_TYPE,
0,
geographicAttributeName,
pszNameString,
attributeMaxLength );
//
// CertGetNameString returns thenumber of characters converted, including the terminating zero character.
// Since the underlying API does not talk about errors, we proceed assuming that zero means
// no string value.
//
return pszNameString.ToString();
}
public TrustDecision Trust
{
set { m_trustDecision = value; }
get { return m_trustDecision; }
}
private void ThrowIfNotComplete()
{
//
// Verify that the Recipient has been populated.
//
bool isComplete = ( null != m_recipientId &&
null != m_subjectName );
if( IdentityType.X509 == m_type )
{
isComplete = isComplete
&& null != m_issuerName
&& !Utility.ArrayIsNullOrEmpty( m_publicKey );
}
if( !isComplete )
{
throw IDT.ThrowHelperError( new SerializationIncompleteException( this.GetType() ) );
}
}
private void AddLogoMetadata(X509Certificate2 cert)
{
X509LogoTypeExtension logoExtension = X509LogoTypeExtension.FromCertificate( cert );
if( null == logoExtension )
{
return;
}
logoExtension.TryDecodeExtension();
m_logoMetadata = logoExtension.Logos;
}
public void Serialize(System.IO.BinaryWriter writer)
{
AgentSerialize( writer );
}
public void AgentSerialize(System.IO.BinaryWriter writer)
{
//
// Make sure that we don't serialize an incomplete object. Serializing null values will result in a
// serialization exception or a corrupt signature.
//
ThrowIfNotComplete();
//
// Write each member to binary stream
//
writer.Write( Version );
writer.Write( (byte)m_type );
writer.Write( m_isCertCached );
//
// Write HA flags and the CN,O,L,S,C fields.
//
writer.Write( (uint)m_recipientParams.m_certHAFlags );
Utility.SerializeString( writer, m_recipientParams.m_cn );
Utility.SerializeString( writer, m_recipientParams.m_organization );
Utility.SerializeString( writer, m_recipientParams.m_locality );
Utility.SerializeString( writer, m_recipientParams.m_state );
Utility.SerializeString( writer, m_recipientParams.m_country );
Utility.SerializeString( writer, m_recipientId );
Utility.SerializeString( writer, m_recipientOrganizationId );
Utility.SerializeString( writer, m_issuerName );
Utility.SerializeString( writer, m_subjectName );
writer.Write( m_privacyNoticeVersion );
Utility.SerializeBytes( writer, m_publicKey );
writer.Write( (byte)m_trustDecision );
if( null == m_logoMetadata )
{
//
// Indicate that there are no logos.
//
writer.Write( 0 );
}
else
{
//
// Write the number of X509Logo objects.
//
writer.Write( m_logoMetadata.Count );
//
// Write each X509Logo object.
//
foreach( X509Logo logo in m_logoMetadata )
{
logo.Serialize( writer );
}
}
writer.Write( m_marker );
}
public void SerializeToStore(System.IO.BinaryWriter writer)
{
//
// Make sure that we don't serialize an incomplete object. Serializing null values will result in a
// serialization exception or a corrupt signature.
//
ThrowIfNotComplete();
//
// Write each member to binary stream
//
writer.Write( Version );
//
// Write HA flags and the CN,O,L,S,C fields.
//
writer.Write( (uint)m_recipientParams.m_certHAFlags );
Utility.SerializeString( writer, m_recipientParams.m_cn );
Utility.SerializeString( writer, m_recipientParams.m_organization );
Utility.SerializeString( writer, m_recipientParams.m_locality );
Utility.SerializeString( writer, m_recipientParams.m_state );
Utility.SerializeString( writer, m_recipientParams.m_country );
Utility.SerializeString( writer, m_recipientId );
Utility.SerializeString( writer, m_recipientOrganizationId );
Utility.SerializeString( writer, m_issuerName );
Utility.SerializeString( writer, m_subjectName );
writer.Write( m_privacyNoticeVersion );
Utility.SerializeBytes( writer, m_publicKey );
writer.Write( (byte)m_trustDecision );
writer.Write( m_marker );
}
public void Deserialize(System.IO.Stream stream)
{
//
// Populate each member from the stream
//
BinaryReader reader = new InfoCardBinaryReader( stream, Encoding.Unicode );
//
// Check the version
//
if( Version != reader.ReadByte() )
{
IDT.Assert( false, "version mismatch deserializing recipient stream" );
}
//
// Read the HA flags and CN,O,L,S,C fields.
//
m_recipientParams = new RecipientCertParameters();
m_recipientParams.m_certHAFlags = (Utility.SubjectAtrributeHAFlags)reader.ReadUInt32();
m_recipientParams.m_cn = Utility.DeserializeString( reader );
m_recipientParams.m_organization = Utility.DeserializeString( reader );
m_recipientParams.m_locality = Utility.DeserializeString( reader );
m_recipientParams.m_state = Utility.DeserializeString( reader );
m_recipientParams.m_country = Utility.DeserializeString( reader );
//
// Read each property from the stream
//
m_recipientId = Utility.DeserializeString( reader );
m_recipientOrganizationId = Utility.DeserializeString( reader );
m_issuerName = Utility.DeserializeString( reader );
m_subjectName = Utility.DeserializeString( reader );
m_privacyNoticeVersion = reader.ReadUInt32();
m_publicKey = reader.ReadBytes( reader.ReadInt32() );
//
// This is not a good way to decided is the identity is of the correct type.
// In V2 we want to be able to write an explicit identity type, but till then
// then we will use the lack of a public key to signify that the recipient is
// for an X509 type
//
if( 0 == m_publicKey.Length )
{
m_type = IdentityType.DNS;
}
else
{
m_type = IdentityType.X509;
}
m_trustDecision = (TrustDecision)reader.ReadByte();
//
// Validate the end of the buffer
//
if( m_marker != reader.ReadByte() )
{
IDT.Assert( false, "Invalid stream detected deserilizing recipient" );
}
//
// Just a correctness check
//
ThrowIfNotComplete();
}
public void Save(StoreConnection con)
{
IDT.TraceDebug( "Saving Recipient..." );
IDT.TraceDebug( ToString() );
//
// Write the Recipient object to the store
//
//
// Try and get the database header information to
// see if this is an insert or update.
//
// Note: The datafield is not part of the projection
// in order to avoid unecessary decryption.
//
DataRow row = TryGetRow( con, QueryDetails.FullHeader );
if( null == row )
{
row = new DataRow();
row.ObjectType = (Int32)StorableObjectType.Recipient;
row.GlobalId = Guid.NewGuid();
}
//
// Populate the parentId index field
//
row.SetIndexValue( SecondaryIndexDefinition.RecipientIdIndex, m_recipientId );
//
// Populate the data object
//
MemoryStream ms = new MemoryStream();
System.IO.BinaryWriter writer = new BinaryWriter( ms, Encoding.Unicode );
SerializeToStore( writer );
row.SetDataField( ms.ToArray() );
//
// Save the row to the database
//
con.Save( row );
//
// Update the row id in the object in case
// this was an insert.
//
m_rowId = row.LocalId;
}
public override string ToString()
{
#if DEBUG
StringBuilder sb = new StringBuilder();
sb.AppendFormat( "Recipient RecipientId:\t{0}\n", m_recipientId );
sb.AppendFormat( "Recipient Issuer Name:\t{0}\n", m_issuerName );
sb.AppendFormat( "Recipient Subject Name:\t{0}\n", m_subjectName );
sb.AppendFormat( "Recipient PrivacyNoticeVersion:\t{0}\n", m_privacyNoticeVersion );
sb.AppendFormat( "TrustDecision:\t{0}\n", m_trustDecision.ToString() );
return sb.ToString();
#else
return base.ToString();
#endif
}
//
// Summary
// Check if the organization is verified
//
public bool IsOrganizationVerified()
{
//
// Any of these flags being set means that the orgaganization is verified
// So we create a mask using these two flags
//
Utility.SubjectAtrributeHAFlags allowedFlags = Utility.SubjectAtrributeHAFlags.Enabled | Utility.SubjectAtrributeHAFlags.OrganizationHA;
return ( this.m_recipientParams.m_certHAFlags & allowedFlags ) == allowedFlags;
}
protected DataRow TryGetRow(StoreConnection con, QueryDetails details)
{
//
// Retrieve a single object from the database
//
DataRow row = con.GetSingleRow(
QueryDetails.FullHeader,
new QueryParameter( SecondaryIndexDefinition.ObjectTypeIndex,
(Int32)StorableObjectType.Recipient ),
new QueryParameter( SecondaryIndexDefinition.RecipientIdIndex,
m_recipientId ) );
return row;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ConnectionManager.cs
- DbConnectionHelper.cs
- XmlSortKey.cs
- MetadataCache.cs
- BinaryMessageEncodingElement.cs
- BufferedOutputStream.cs
- GradientStop.cs
- WebPermission.cs
- ChangeNode.cs
- VirtualDirectoryMappingCollection.cs
- SafeNativeMethods.cs
- Input.cs
- PriorityChain.cs
- XmlAttributeCollection.cs
- TrackingProfileDeserializationException.cs
- EncryptionUtility.cs
- Brush.cs
- PerformanceCounterManager.cs
- ProxyDataContractResolver.cs
- ExpressionBuilder.cs
- CallTemplateAction.cs
- SettingsPropertyValue.cs
- DataServiceQuery.cs
- CodeTypeConstructor.cs
- EntityDataSourceQueryBuilder.cs
- RangeValuePattern.cs
- DataControlFieldCell.cs
- UICuesEvent.cs
- WebPartEditorCancelVerb.cs
- UTF32Encoding.cs
- DetailsViewModeEventArgs.cs
- OdbcConnectionStringbuilder.cs
- PointAnimation.cs
- HttpStaticObjectsCollectionBase.cs
- IOThreadScheduler.cs
- CombinedGeometry.cs
- EntityDataSourceStatementEditorForm.cs
- DataGridItemEventArgs.cs
- MetaColumn.cs
- HttpChannelBindingToken.cs
- ProcessInfo.cs
- NetworkInformationPermission.cs
- DesignerCommandSet.cs
- ValidatorCollection.cs
- ChildrenQuery.cs
- ValidationVisibilityAttribute.cs
- XMLSchema.cs
- DataContractAttribute.cs
- Attribute.cs
- SplitterPanel.cs
- ResourcePool.cs
- NullToBooleanConverter.cs
- MenuBase.cs
- TypeElement.cs
- ParserExtension.cs
- TypedTableBaseExtensions.cs
- CodeDefaultValueExpression.cs
- DocumentReferenceCollection.cs
- PropertyTab.cs
- WindowsListViewItemCheckBox.cs
- externdll.cs
- ProcessModelInfo.cs
- MouseGestureValueSerializer.cs
- regiisutil.cs
- CompareValidator.cs
- DataPagerFieldCommandEventArgs.cs
- SimpleLine.cs
- XmlQueryOutput.cs
- RuntimeCompatibilityAttribute.cs
- CellCreator.cs
- PenThreadPool.cs
- ToolBarButton.cs
- AnnotationResourceCollection.cs
- TextTrailingWordEllipsis.cs
- LoginName.cs
- validation.cs
- AsyncDataRequest.cs
- ImageInfo.cs
- StringArrayEditor.cs
- RequestUriProcessor.cs
- JournalEntryListConverter.cs
- ConnectionStringsExpressionBuilder.cs
- NodeLabelEditEvent.cs
- JobStaple.cs
- ThreadStaticAttribute.cs
- ArraySegment.cs
- ArgumentDesigner.xaml.cs
- PointValueSerializer.cs
- FixedSOMContainer.cs
- CodeTryCatchFinallyStatement.cs
- ToolStripLabel.cs
- Style.cs
- PlaceHolder.cs
- RuntimeArgumentHandle.cs
- Vector3DCollection.cs
- ProxyGenerationError.cs
- ToolStripInSituService.cs
- IntSumAggregationOperator.cs
- FactoryGenerator.cs
- MatrixAnimationBase.cs