Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Security / Cryptography / ECDsaCng.cs / 1305376 / ECDsaCng.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== using System; using System.Diagnostics; using System.IO; using System.Security; using System.Security.Permissions; using System.Diagnostics.Contracts; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { ////// Wrapper for NCrypt's implementation of elliptic curve DSA /// [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class ECDsaCng : ECDsa { private static KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(256, 384, 128), new KeySizes(521, 521, 0) }; private CngKey m_key; private CngAlgorithm m_hashAlgorithm = CngAlgorithm.Sha256; // // Constructors // public ECDsaCng() : this(521) { Contract.Ensures(LegalKeySizesValue != null); } //// [System.Security.SecurityCritical] public ECDsaCng(int keySize) { Contract.Ensures(LegalKeySizesValue != null); if (!NCryptNative.NCryptSupported) { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported)); } LegalKeySizesValue = s_legalKeySizes; KeySize = keySize; } //// // [System.Security.SecurityCritical] public ECDsaCng(CngKey key) { Contract.Ensures(LegalKeySizesValue != null); Contract.Ensures(m_key != null && m_key.AlgorithmGroup == CngAlgorithmGroup.ECDsa); if (key == null) { throw new ArgumentNullException("key"); } if (key.AlgorithmGroup != CngAlgorithmGroup.ECDsa) { throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDsaRequiresECDsaKey), "key"); } if (!NCryptNative.NCryptSupported) { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported)); } LegalKeySizesValue = s_legalKeySizes; // Make a copy of the key so that we continue to work if it gets disposed before this algorithm // // This requires an assert for UnmanagedCode since we'll need to access the raw handles of the key // and the handle constructor of CngKey. The assert is safe since ECDsaCng will never expose the // key handles to calling code (without first demanding UnmanagedCode via the Handle property of // CngKey). new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); Key = CngKey.Open(key.Handle, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None); CodeAccessPermission.RevertAssert(); KeySize = m_key.KeySize; } ///// // /// Hash algorithm to use when generating a signature over arbitrary data /// public CngAlgorithm HashAlgorithm { get { Contract.Ensures(Contract.Result() != null); return m_hashAlgorithm; } set { Contract.Ensures(m_hashAlgorithm != null); if (value == null) { throw new ArgumentNullException("value"); } m_hashAlgorithm = value; } } /// /// Key to use for signing /// public CngKey Key { get { Contract.Ensures(Contract.Result() != null); Contract.Ensures(Contract.Result ().AlgorithmGroup == CngAlgorithmGroup.ECDsa); Contract.Ensures(m_key != null && m_key.AlgorithmGroup == CngAlgorithmGroup.ECDsa); // If the size of the key no longer matches our stored value, then we need to replace it with // a new key of the correct size. if (m_key != null && m_key.KeySize != KeySize) { m_key.Dispose(); m_key = null; } if (m_key == null) { // Map the current key size to a CNG algorithm name CngAlgorithm algorithm = null; switch (KeySize) { case 256: algorithm = CngAlgorithm.ECDsaP256; break; case 384: algorithm = CngAlgorithm.ECDsaP384; break; case 521: algorithm = CngAlgorithm.ECDsaP521; break; default: Debug.Assert(false, "Illegal key size set"); break; } m_key = CngKey.Create(algorithm); } return m_key; } private set { Contract.Requires(value != null); Contract.Ensures(m_key != null && m_key.AlgorithmGroup == CngAlgorithmGroup.ECDsa); if (value.AlgorithmGroup != CngAlgorithmGroup.ECDsa) { throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDsaRequiresECDsaKey)); } if (m_key != null) { m_key.Dispose(); } // // We do not duplicate the handle because the only time the user has access to the key itself // to dispose underneath us is when they construct via the CngKey constructor, which does a // copy. Otherwise all key lifetimes are controlled directly by the ECDsaCng class. // m_key = value; KeySize = m_key.KeySize; } } /// /// Clean up the algorithm /// protected override void Dispose(bool disposing) { try { if (m_key != null) { m_key.Dispose(); } } finally { base.Dispose(disposing); } } // // XML Import // // #ECCXMLFormat // // There is currently not a standard XML format for ECC keys, so we will not implement the default // To/FromXmlString so that we're not tied to one format when a standard one does exist. Instead we'll // use an overload which allows the user to specify the format they'd like to serialize into. // // See code:System.Security.Cryptography.Rfc4050KeyFormatter#RFC4050ECKeyFormat for information about // the currently supported format. // public override void FromXmlString(string xmlString) { throw new NotImplementedException(SR.GetString(SR.Cryptography_ECXmlSerializationFormatRequired)); } public void FromXmlString(string xml, ECKeyXmlFormat format) { if (xml == null) { throw new ArgumentNullException("xml"); } if (format != ECKeyXmlFormat.Rfc4050) { throw new ArgumentOutOfRangeException("format"); } Key = Rfc4050KeyFormatter.FromXml(xml); } // // Signature generation // public byte[] SignData(byte[] data) { Contract.Ensures(Contract.Result() != null); if (data == null) { throw new ArgumentNullException("data"); } return SignData(data, 0, data.Length); } // // [System.Security.SecurityCritical] public byte[] SignData(byte[] data, int offset, int count) { Contract.Ensures(Contract.Result// // // () != null); if (data == null) { throw new ArgumentNullException("data"); } if (offset < 0 || offset > data.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || count > data.Length - offset) { throw new ArgumentOutOfRangeException("count"); } using (BCryptHashAlgorithm hashAlgorithm = new BCryptHashAlgorithm(HashAlgorithm, BCryptNative.ProviderName.MicrosoftPrimitiveProvider)) { hashAlgorithm.HashCore(data, offset, count); byte[] hashValue = hashAlgorithm.HashFinal(); return SignHash(hashValue); } } // // [System.Security.SecurityCritical] public byte[] SignData(Stream data) { Contract.Ensures(Contract.Result// // // () != null); if (data == null) { throw new ArgumentNullException("data"); } using (BCryptHashAlgorithm hashAlgorithm = new BCryptHashAlgorithm(HashAlgorithm, BCryptNative.ProviderName.MicrosoftPrimitiveProvider)) { hashAlgorithm.HashStream(data); byte[] hashValue = hashAlgorithm.HashFinal(); return SignHash(hashValue); } } // // [System.Security.SecurityCritical] public override byte[] SignHash(byte[] hash) { if (hash == null) { throw new ArgumentNullException("hash"); } // Make sure we're allowed to sign using this key KeyContainerPermission permission = Key.BuildKeyContainerPermission(KeyContainerPermissionFlags.Sign); if (permission != null) { permission.Demand(); } // Now that know we have permission to use this key for signing, pull the key value out, which // will require unmanaged code permission new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); SafeNCryptKeyHandle keyHandle = Key.Handle; CodeAccessPermission.RevertAssert(); return NCryptNative.SignHash(keyHandle, hash); } // // XML Export // // See code:System.Security.Cryptography.ECDsaCng#ECCXMLFormat and // code:System.Security.Cryptography.Rfc4050KeyFormatter#RFC4050ECKeyFormat for information about // XML serialization of elliptic curve keys // public override string ToXmlString(bool includePrivateParameters) { throw new NotImplementedException(SR.GetString(SR.Cryptography_ECXmlSerializationFormatRequired)); } public string ToXmlString(ECKeyXmlFormat format) { Contract.Ensures(Contract.Result// // // () != null); if (format != ECKeyXmlFormat.Rfc4050) { throw new ArgumentOutOfRangeException("format"); } return Rfc4050KeyFormatter.ToXml(Key); } // // Signature verification // public bool VerifyData(byte[] data, byte[] signature) { if (data == null) { throw new ArgumentNullException("data"); } return VerifyData(data, 0, data.Length, signature); } // // [System.Security.SecurityCritical] public bool VerifyData(byte[] data, int offset, int count, byte[] signature) { if (data == null) { throw new ArgumentNullException("data"); } if (offset < 0 || offset > data.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || count > data.Length - offset) { throw new ArgumentOutOfRangeException("count"); } if (signature == null) { throw new ArgumentNullException("signature"); } using (BCryptHashAlgorithm hashAlgorithm = new BCryptHashAlgorithm(HashAlgorithm, BCryptNative.ProviderName.MicrosoftPrimitiveProvider)) { hashAlgorithm.HashCore(data, offset, count); byte[] hashValue = hashAlgorithm.HashFinal(); return VerifyHash(hashValue, signature); } } //// // // // [System.Security.SecurityCritical] public bool VerifyData(Stream data, byte[] signature) { if (data == null) { throw new ArgumentNullException("data"); } if (signature == null) { throw new ArgumentNullException("signature"); } using (BCryptHashAlgorithm hashAlgorithm = new BCryptHashAlgorithm(HashAlgorithm, BCryptNative.ProviderName.MicrosoftPrimitiveProvider)) { hashAlgorithm.HashStream(data); byte[] hashValue = hashAlgorithm.HashFinal(); return VerifyHash(hashValue, signature); } } //// // // // [System.Security.SecurityCritical] public override bool VerifyHash(byte[] hash, byte[] signature) { if (hash == null) { throw new ArgumentNullException("hash"); } if (signature == null) { throw new ArgumentNullException("signature"); } // We need to get the raw key handle to verify the signature. Asserting here is safe since verifiation // is not a protected operation, and we do not expose the handle to the user code. new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); SafeNCryptKeyHandle keyHandle = Key.Handle; CodeAccessPermission.RevertAssert(); return NCryptNative.VerifySignature(keyHandle, hash, signature); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.// //
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- UniformGrid.cs
- PeerResolver.cs
- DateRangeEvent.cs
- SQLStringStorage.cs
- CreateParams.cs
- XmlException.cs
- DesignerCatalogPartChrome.cs
- WSHttpTransportSecurityElement.cs
- safePerfProviderHandle.cs
- TokenizerHelper.cs
- ElementHostPropertyMap.cs
- WindowManager.cs
- FatalException.cs
- AnimationClock.cs
- Monitor.cs
- DesignTimeParseData.cs
- cache.cs
- WorkflowRuntime.cs
- GeneralTransform2DTo3D.cs
- IdentityValidationException.cs
- RightsManagementEncryptionTransform.cs
- ApplicationDirectory.cs
- XPathScanner.cs
- FormattedTextSymbols.cs
- MailMessageEventArgs.cs
- ComplexType.cs
- StopStoryboard.cs
- Mappings.cs
- PolicyException.cs
- BinarySerializer.cs
- Empty.cs
- Dispatcher.cs
- Pair.cs
- KeyboardEventArgs.cs
- sapiproxy.cs
- SetStoryboardSpeedRatio.cs
- DataListCommandEventArgs.cs
- MULTI_QI.cs
- IsolatedStorageFile.cs
- Transform.cs
- ErrorTableItemStyle.cs
- XmlConvert.cs
- CodeTypeReference.cs
- NavigationHelper.cs
- IntMinMaxAggregationOperator.cs
- XmlAttributeOverrides.cs
- CodeValidator.cs
- MessageSmuggler.cs
- Debug.cs
- FrameworkContentElement.cs
- CodeAttributeArgument.cs
- JsonServiceDocumentSerializer.cs
- WebHeaderCollection.cs
- Inline.cs
- ProcessProtocolHandler.cs
- EntityWithKeyStrategy.cs
- SqlDataSourceQueryConverter.cs
- Style.cs
- StructuredType.cs
- NumberAction.cs
- XmlValueConverter.cs
- SchemaInfo.cs
- FolderLevelBuildProviderAppliesToAttribute.cs
- XmlTextEncoder.cs
- GcSettings.cs
- DataGridHelper.cs
- formatter.cs
- InvalidOperationException.cs
- MultiView.cs
- WebReferenceOptions.cs
- GridViewCancelEditEventArgs.cs
- Region.cs
- FixedSOMTable.cs
- VisualBrush.cs
- StringDictionary.cs
- StagingAreaInputItem.cs
- GrammarBuilderPhrase.cs
- SystemException.cs
- CompiledWorkflowDefinitionContext.cs
- Cursor.cs
- AbstractExpressions.cs
- ZipIOLocalFileDataDescriptor.cs
- GridViewColumnHeader.cs
- sapiproxy.cs
- HTTP_SERVICE_CONFIG_URLACL_PARAM.cs
- Automation.cs
- AnimationStorage.cs
- ApplicationSecurityManager.cs
- DataContractSerializerOperationBehavior.cs
- SecurityTokenTypes.cs
- TreeIterators.cs
- GenericWebPart.cs
- StrongNameUtility.cs
- DeriveBytes.cs
- ConfigurationPropertyAttribute.cs
- DoubleCollection.cs
- x509store.cs
- MulticastOption.cs
- VisualStyleElement.cs
- ExceptionUtility.cs