Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / LedgerEntry.cs / 1 / LedgerEntry.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.Threading;
using Microsoft.InfoCards.Diagnostics;
using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace;
//
// Summary
// This class represents a ledger entry
//
internal class LedgerEntry
{
const Int32 InvalidRow = 0;
const byte Version = 1;
const byte m_marker = 29;
bool m_isDirty;
DateTime m_disclosureDate = DateTime.MinValue;
string m_recipientId;
Recipient m_recipient;
byte[] m_subjectKey;
string[] m_disclosedClaims;
Uri m_infoCardId;
string m_immediateRecipientOrgId;
Int32 m_rowId = InvalidRow;
//
// Summary
// Constructor for creating a ledger entry using the serialized ledger object
//
// Parameters
// stream - Stream containing the serialized object
// connection - Connection to the store.
//
public LedgerEntry( Stream stream, StoreConnection connection )
{
IDT.Assert( null != stream, " Null input stream" );
IDT.Assert( null != connection, "Null storeconnection" );
m_isDirty = false;
Deserialize( stream );
//
// Read the recipient from the store
//
DataRow row = connection.GetSingleRow(
new QueryParameter( SecondaryIndexDefinition.ObjectTypeIndex,
(Int32)StorableObjectType.Recipient ),
new QueryParameter( SecondaryIndexDefinition.RecipientIdIndex,
m_recipientId ) );
IDT.Assert( null != row,
"Recipient should always exist in store before a ledger entry is created " );
if ( null != row )
{
m_recipient = new Recipient( new MemoryStream( row.GetDataField() ) );
}
ThrowIfNotComplete();
}
//
// Summary
// Static constructor for creating a ledger entry for a recipient
// Use this factory method to also create the SubjectKey [NewLedgerEntry --
// as opposed to a constructor signifies doing an expensive operation]
//
// Remarks:
// Callee must call Array.Clear (if appropriate)
//
// Parameters
// infoCardId - Id of the parent infocard.
// recipient - Recipient associated with this ledger entry.
// masterkey - The masterkey
//
public static LedgerEntry NewLedgerEntry( Uri infoCardId, Recipient recipient, byte[] masterKey, string immediateTokenRecipientOrganizationIdentifier )
{
return new LedgerEntry( infoCardId, recipient, masterKey, immediateTokenRecipientOrganizationIdentifier );
}
//
// Summary
// Constructor for creating a ledger entry for a recipient
//
// Remarks
// Callee must call Array.Clear (if appropriate)
//
// Parameters
// infoCardId - Id of the parent infocard.
// recipient - Recipient associated with this ledger entry.
// masterKey - Masterkey of the infoCard, callee must call Array.Clear
//
public LedgerEntry( Uri infoCardId, Recipient recipient, byte[] masterKey, string immediateTokenRecipientOrganizationIdentifier )
{
IDT.Assert( null != recipient, "Null recipient" );
IDT.Assert( null != infoCardId, "Null infocard ID" );
m_isDirty = true;
m_infoCardId = infoCardId;
m_disclosureDate = DateTime.Now;
m_recipient = recipient;
m_recipientId = recipient.RecipientId;
m_immediateRecipientOrgId = immediateTokenRecipientOrganizationIdentifier;
//
// Generate a new RSA Key pair for the subject
//
//
// POR is to use the Public Key of the target recipient
// for the target recipient entropy. We could also use the
// FQDN for the organization instead. The latter approach will only work
// if organizational certs started expressing fully qualified and
// globally unique org. But this is not the case with SSL certs for example,
// where only the CN component of the subject DN is really used
// and specified.
//
m_subjectKey = RsaKeyGen.CreateRsaKeyPairX931(
masterKey,
Convert.FromBase64String( immediateTokenRecipientOrganizationIdentifier ) );
ThrowIfNotComplete();
}
//
// Summary
// Update the subjectKey if the immediate token recipient has changed
//
// Parameters
// recipient - Organization id of the immediate recipient of the token being created.
// masterKey - Masterkey of the infoCard, callee must call Array.Clear
//
// Returns true if the the subject key was updated
//
public bool CheckAndUpdateSubjectKey( string immediateTokenRecipientOrgId, byte[] masterKey )
{
//
// Recreate the RSA key pair if the id has changed
//
if ( m_immediateRecipientOrgId != immediateTokenRecipientOrgId )
{
m_immediateRecipientOrgId = immediateTokenRecipientOrgId;
m_subjectKey = RsaKeyGen.CreateRsaKeyPairX931(
masterKey,
Convert.FromBase64String( immediateTokenRecipientOrgId ) );
return true;
}
return false;
}
public bool IsDirty
{
get { return m_isDirty; }
}
public DateTime DisclosureDate
{
//
// Set by GetTokenRequest
//
set
{
m_disclosureDate = value;
m_isDirty = true;
}
}
public byte[] SubjectKey
{
get
{
IDT.Assert( !Utility.ArrayIsNullOrEmpty( m_subjectKey ), "SubjectKey not populated!" );
return m_subjectKey;
}
}
public string[] DisclosedClaims
{
get
{
return m_disclosedClaims;
}
set
{
m_disclosedClaims = value;
m_isDirty = true;
}
}
public Recipient Recipient
{
get { return m_recipient; }
}
// See 33231, 33232.
// Get referenced by agent\LedgerManagement ddsuites.
//
public Uri InfoCardId
{
get { return m_infoCardId; }
}
//
// Summary
// Throws if ledger entry has not been populated.
//
public void ThrowIfNotComplete()
{
bool isComplete = (null != m_immediateRecipientOrgId &&
null != m_recipientId &&
!Utility.ArrayIsNullOrEmpty( m_subjectKey ) &&
null != m_infoCardId &&
DateTime.MinValue != m_disclosureDate);
if ( !isComplete )
{
throw IDT.ThrowHelperError( new SerializationIncompleteException( this.GetType() ) );
}
}
//
// Summary
// Serialize the ledger entry
//
// Parameters
// writer - The binary writer the object is serialized to.
//
public void Serialize( 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( m_disclosureDate.ToFileTimeUtc() );
Utility.SerializeString( writer, m_recipientId );
Utility.SerializeString( writer, m_immediateRecipientOrgId );
Utility.SerializeBytes( writer, m_subjectKey );
Utility.SerializeUri( writer, m_infoCardId );
writer.Write( (Int32)(null == m_disclosedClaims ? 0 : m_disclosedClaims.Length) );
if ( null != m_disclosedClaims )
{
foreach ( string claimId in m_disclosedClaims )
{
Utility.SerializeString( writer, claimId );
}
}
writer.Write( m_marker );
}
//
// Summary
// Deserialize the ledger entry
//
// Parameters
// reader - The binary reader the object is serialized to.
//
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 ledger" );
}
//
// Read each property from the stream
//
m_disclosureDate = DateTime.FromFileTimeUtc( reader.ReadInt64() );
m_recipientId = Utility.DeserializeString( reader );
m_immediateRecipientOrgId = Utility.DeserializeString( reader );
m_subjectKey = reader.ReadBytes( reader.ReadInt32() );
m_infoCardId = Utility.DeserializeUri( reader );
Int32 n = reader.ReadInt32();
if ( n > 0 )
{
m_disclosedClaims = new string[ n ];
for ( Int32 i = 0; i < n; i++ )
{
m_disclosedClaims[ i ] = Utility.DeserializeString( reader );
}
}
//
// Validate the end of the buffer
//
if ( m_marker != reader.ReadByte() )
{
IDT.Assert( false, "Invalid stream detected deserializing ledger" );
}
//
// Just a correctness check
//
ThrowIfNotComplete();
//
// The entry is only deserialized when reading from the store therefore mark as not dirty.
//
m_isDirty = false;
}
public void Save( StoreConnection con )
{
IDT.TraceDebug( "Saving LedgerEntry..." );
IDT.TraceDebug( ToString() );
//
// Write the ledger entry 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.LedgerEntry;
row.GlobalId = Guid.NewGuid();
}
//
// Populate the parentId index field
//
row.SetIndexValue( SecondaryIndexDefinition.ParentIdIndex,
GlobalId.DeriveFrom( m_infoCardId.ToString() ) );
row.SetIndexValue( SecondaryIndexDefinition.RecipientIdIndex, m_recipientId );
//
// Populate the data object
//
MemoryStream ms = new MemoryStream();
System.IO.BinaryWriter writer = new BinaryWriter( ms, Encoding.Unicode );
Serialize( writer );
row.SetDataField( ms.ToArray() );
//
// Before saving the ledger, we need to make sure that the recipient has been saved
//
DataRow recipientRow = con.GetSingleRow(
QueryDetails.FullHeader,
new QueryParameter( SecondaryIndexDefinition.ObjectTypeIndex,
(Int32)StorableObjectType.Recipient ),
new QueryParameter( SecondaryIndexDefinition.RecipientIdIndex,
m_recipientId ) );
if ( null != row )
{
con.Save( row );
}
else
{
IDT.Assert( false, "Currupt store - no recipient found for ledger" );
}
//
// Update the row id in the object in case
// this was an insert.
//
m_rowId = row.LocalId;
//
// Mark object as not dirty.
//
m_isDirty = false;
}
//
// Summary
// Write the object to a string
//
public override string ToString()
{
#if DEBUG
StringBuilder sb = new StringBuilder();
sb.AppendFormat( "InfoCard Id:\t{0}\n", m_infoCardId.ToString() );
sb.AppendFormat( "Disclosure Date:\t{0}\n", m_disclosureDate );
sb.AppendFormat( "Recipient RecipientId:\t{0}\n", m_recipientId );
sb.AppendFormat( "Recipient ImmediateRecipientOrgId:\t{0}\n", m_immediateRecipientOrgId );
sb.AppendFormat( "Subject Key: not shown\n" );
sb.AppendFormat( "Disclosed Claims:\n" );
if ( null != m_disclosedClaims )
{
foreach ( string uri in m_disclosedClaims )
{
sb.AppendFormat( "{0}\n", uri );
}
}
return sb.ToString();
#else
return base.ToString();
#endif
}
//
// Summary
// Retrieve the datarow for the ledger entry from the store for the specified query
//
// Parameters
// con - store connection
// details - Query to be used.
//
// Return
// The datarow retrieved from the store.
//
protected DataRow TryGetRow( StoreConnection con, QueryDetails details )
{
IDT.Assert( null != m_infoCardId, "populate infocard before retrieving ledger" );
//
// Retrieve a single object from the database
//
DataRow row = con.GetSingleRow(
QueryDetails.FullHeader,
new QueryParameter( SecondaryIndexDefinition.ObjectTypeIndex,
(Int32)StorableObjectType.LedgerEntry ),
new QueryParameter( SecondaryIndexDefinition.RecipientIdIndex,
m_recipientId ),
new QueryParameter( SecondaryIndexDefinition.ParentIdIndex,
GlobalId.DeriveFrom( m_infoCardId.ToString() ) ) );
return row;
}
}
}
//////////////////////////////////////////////////////////////////////////////
// Functions that could potentially be useful in future:
//////////////////////////////////////////////////////////////////////////////
//
// Summary
// Retrieve the datarow for the ledger entry from the store for the specified query.
// Checks if the returned row is a ledger entry.
//
// Parameters
// con - store connection
// details - Query to be used.
//
// Return
// The datarow retrieved from the store.
//
//protected DataRow GetRow( StoreConnection con, QueryDetails details )
//{
// DataRow row = TryGetRow( con, details );
// //
// // Verify that an infocard row was returned
// //
// if( null != row || (Int32)StorableObjectType.LedgerEntry != row.ObjectType )
// {
// throw IDT.ThrowHelperError( new InvalidOperationException(
// SR.GetString( SR.LedgerEntryIncorrectType ) ) );
// }
// return row;
//}
//public void Get( StoreConnection con )
//{
// // Retrieve the row for the object from the database
// DataRow row = GetRow( con, QueryDetails.FullRow );
// // Populate the infocard using the byte array
// Deserialize( new MemoryStream( row.GetDataField() ) );
// // Update the row id from the database
// m_rowId = row.LocalId;
//}
// 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
- PeerApplication.cs
- RegisteredArrayDeclaration.cs
- XmlComment.cs
- PrintEvent.cs
- Subtree.cs
- DoubleIndependentAnimationStorage.cs
- ImageEditor.cs
- ScriptIgnoreAttribute.cs
- EntityViewGenerationConstants.cs
- SqlDataSourceQueryEditor.cs
- TdsParameterSetter.cs
- ClipboardData.cs
- XLinq.cs
- SecurityRuntime.cs
- PanelStyle.cs
- StringCollection.cs
- OleCmdHelper.cs
- DataTrigger.cs
- WebPartConnectVerb.cs
- WindowsScrollBar.cs
- StyleHelper.cs
- QueryCursorEventArgs.cs
- SourceLineInfo.cs
- BooleanToVisibilityConverter.cs
- DataGridViewAutoSizeColumnsModeEventArgs.cs
- Slider.cs
- messageonlyhwndwrapper.cs
- ContextInformation.cs
- XmlSchemaSequence.cs
- PreviewPrintController.cs
- DesignerProperties.cs
- TryExpression.cs
- MenuItemBindingCollection.cs
- GridViewPageEventArgs.cs
- UnauthorizedWebPart.cs
- TextFormatterHost.cs
- UInt32Storage.cs
- ConnectionManagementElementCollection.cs
- DrawToolTipEventArgs.cs
- SBCSCodePageEncoding.cs
- FixedTextView.cs
- StreamWriter.cs
- XmlBufferedByteStreamReader.cs
- CssClassPropertyAttribute.cs
- DynamicUpdateCommand.cs
- XPathParser.cs
- HtmlControlAdapter.cs
- LoginCancelEventArgs.cs
- JournalEntryStack.cs
- ObjectConverter.cs
- BridgeDataRecord.cs
- LinkedResourceCollection.cs
- SchemaNotation.cs
- FontSourceCollection.cs
- ToolStripPanelRow.cs
- HttpServerVarsCollection.cs
- ViewEventArgs.cs
- CounterSample.cs
- DocumentSchemaValidator.cs
- Dispatcher.cs
- SecurityTokenAuthenticator.cs
- TraceEventCache.cs
- FieldNameLookup.cs
- SessionEndedEventArgs.cs
- WindowsListViewScroll.cs
- DefaultAssemblyResolver.cs
- WebServiceReceiveDesigner.cs
- ReadOnlyHierarchicalDataSource.cs
- XmlExtensionFunction.cs
- OperationCanceledException.cs
- Win32SafeHandles.cs
- ObservableCollection.cs
- AmbientProperties.cs
- CustomAssemblyResolver.cs
- Attributes.cs
- XmlSchemaAny.cs
- AQNBuilder.cs
- OleDbFactory.cs
- RandomDelaySendsAsyncResult.cs
- TextFormatterImp.cs
- DecimalAnimationUsingKeyFrames.cs
- GC.cs
- SymbolEqualComparer.cs
- WebPageTraceListener.cs
- Inflater.cs
- DispatcherProcessingDisabled.cs
- FullTextBreakpoint.cs
- BasicCellRelation.cs
- Model3D.cs
- ExportOptions.cs
- ArraySubsetEnumerator.cs
- COM2IPerPropertyBrowsingHandler.cs
- Compilation.cs
- CompModSwitches.cs
- SymLanguageVendor.cs
- PtsContext.cs
- Span.cs
- OperationResponse.cs
- DuplicateDetector.cs
- EntityDataSourceColumn.cs