DSACryptoServiceProvider.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Security / Cryptography / DSACryptoServiceProvider.cs / 1305376 / DSACryptoServiceProvider.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// [....]
// 
 
//
// DSACryptoServiceProvider.cs 
//
// CSP-based implementation of DSA
//
 
namespace System.Security.Cryptography {
    using System; 
    using System.IO; 
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Permissions; 
    using System.Globalization;
    using System.Runtime.Versioning;
    using System.Diagnostics.Contracts;
 
    // Object layout of the DSAParameters structure
    internal class DSACspObject { 
        internal byte[] P; 
        internal byte[] Q;
        internal byte[] G; 
        internal byte[] Y;
        internal byte[] J;
        internal byte[] X;
        internal byte[] Seed; 
        internal int Counter;
    } 
 
    [System.Runtime.InteropServices.ComVisible(true)]
    public sealed class DSACryptoServiceProvider : DSA, ICspAsymmetricAlgorithm { 
        private int _dwKeySize;
        private CspParameters _parameters;
        private bool _randomKeyContainer;
        [System.Security.SecurityCritical /*auto-generated*/] 
        private SafeProvHandle _safeProvHandle;
        [System.Security.SecurityCritical /*auto-generated*/] 
        private SafeKeyHandle _safeKeyHandle; 
        private SHA1CryptoServiceProvider _sha1;
 
        private static CspProviderFlags s_UseMachineKeyStore = 0;

        //
        // public constructors 
        //
 
        [ResourceExposure(ResourceScope.None)] 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        public DSACryptoServiceProvider() 
            : this(0, new CspParameters(Constants.PROV_DSS_DH, null, null, s_UseMachineKeyStore)) {
        }

        [ResourceExposure(ResourceScope.None)] 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        public DSACryptoServiceProvider(int dwKeySize) 
            : this(dwKeySize, new CspParameters(Constants.PROV_DSS_DH, null, null, s_UseMachineKeyStore)) { 
        }
 
        public DSACryptoServiceProvider(CspParameters parameters)
            : this(0, parameters) {
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public DSACryptoServiceProvider(int dwKeySize, CspParameters parameters) { 
            if (dwKeySize < 0) 
                throw new ArgumentOutOfRangeException("dwKeySize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            Contract.EndContractBlock(); 

            _parameters = Utils.SaveCspParameters(CspAlgorithmType.Dss, parameters, s_UseMachineKeyStore, ref _randomKeyContainer);
            LegalKeySizesValue = new KeySizes[] { new KeySizes(512, 1024, 64) }; // per the DSS spec
            _dwKeySize = dwKeySize; 
            _sha1 = new SHA1CryptoServiceProvider();
 
            // If this is not a random container we generate, create it eagerly 
            // in the constructor so we can report any errors now.
            if (!_randomKeyContainer || Environment.GetCompatibilityFlag(CompatibilityFlag.EagerlyGenerateRandomAsymmKeys)) 
                GetKeyPair();
        }

        // 
        // private methods
        // 
 
        [System.Security.SecurityCritical]  // auto-generated
        private void GetKeyPair () { 
            if (_safeKeyHandle == null) {
                lock (this) {
                    if (_safeKeyHandle == null)
                        Utils.GetKeyPairHelper(CspAlgorithmType.Dss, _parameters, _randomKeyContainer, _dwKeySize, ref _safeProvHandle, ref _safeKeyHandle); 
                }
            } 
        } 

        [System.Security.SecuritySafeCritical] // overrides public transparent member 
        protected override void Dispose(bool disposing) {
            base.Dispose(disposing);

            if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed) 
                _safeKeyHandle.Dispose();
            if (_safeProvHandle != null && !_safeProvHandle.IsClosed) 
                _safeProvHandle.Dispose(); 
        }
 
        //
        // public properties
        //
 
        [System.Runtime.InteropServices.ComVisible(false)]
        public bool PublicOnly { 
            [System.Security.SecuritySafeCritical]  // auto-generated 
            get {
                GetKeyPair(); 
                byte[] publicKey = (byte[]) Utils._GetKeyParameter(_safeKeyHandle, Constants.CLR_PUBLICKEYONLY);
                return (publicKey[0] == 1);
            }
        } 

        [System.Runtime.InteropServices.ComVisible(false)] 
        public CspKeyContainerInfo CspKeyContainerInfo { 
            [System.Security.SecuritySafeCritical]  // auto-generated
            get { 
                GetKeyPair();
                return new CspKeyContainerInfo(_parameters, _randomKeyContainer);
            }
        } 

        public override int KeySize { 
            [System.Security.SecuritySafeCritical]  // auto-generated 
            get {
                GetKeyPair(); 
                byte[] keySize = (byte[]) Utils._GetKeyParameter(_safeKeyHandle, Constants.CLR_KEYLEN);
                _dwKeySize = (keySize[0] | (keySize[1] << 8) | (keySize[2] << 16) | (keySize[3] << 24));
                return _dwKeySize;
            } 
        }
 
        public override string KeyExchangeAlgorithm { 
            get { return null; }
        } 

        public override string SignatureAlgorithm {
            get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }
        } 

        public static bool UseMachineKeyStore { 
            get { return (s_UseMachineKeyStore == CspProviderFlags.UseMachineKeyStore); } 
            set { s_UseMachineKeyStore = (value ? CspProviderFlags.UseMachineKeyStore : 0); }
        } 

        public bool PersistKeyInCsp {
            [System.Security.SecuritySafeCritical]  // auto-generated
            get { 
                if (_safeProvHandle == null) {
                    lock (this) { 
                        if (_safeProvHandle == null) 
                            _safeProvHandle = Utils.CreateProvHandle(_parameters, _randomKeyContainer);
                    } 
                }
                return Utils.GetPersistKeyInCsp(_safeProvHandle);
            }
            [System.Security.SecuritySafeCritical]  // auto-generated 
            set {
                bool oldPersistKeyInCsp = this.PersistKeyInCsp; 
                if (value == oldPersistKeyInCsp) 
                    return;
 
                KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
                if (!value) {
                    KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Delete);
                    kp.AccessEntries.Add(entry); 
                } else {
                    KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Create); 
                    kp.AccessEntries.Add(entry); 
                }
                kp.Demand(); 

                Utils.SetPersistKeyInCsp(_safeProvHandle, value);
            }
        } 

        // 
        // public methods 
        //
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public override DSAParameters ExportParameters (bool includePrivateParameters) {
            GetKeyPair();
            if (includePrivateParameters) { 
                KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
                KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Export); 
                kp.AccessEntries.Add(entry); 
                kp.Demand();
            } 
            DSACspObject dsaCspObject = new DSACspObject();
            int blobType = includePrivateParameters ? Constants.PRIVATEKEYBLOB : Constants.PUBLICKEYBLOB;
            // _ExportKey will check for failures and throw an exception
            Utils._ExportKey(_safeKeyHandle, blobType, dsaCspObject); 
            return DSAObjectToStruct(dsaCspObject);
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [System.Runtime.InteropServices.ComVisible(false)] 
        public byte[] ExportCspBlob (bool includePrivateParameters) {
            GetKeyPair();
            return Utils.ExportCspBlobHelper(includePrivateParameters, _parameters, _safeKeyHandle);
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public override void ImportParameters(DSAParameters parameters) { 
            DSACspObject dsaCspObject = DSAStructToObject(parameters);
            // Free the current key handle 
            if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed)
                _safeKeyHandle.Dispose();
            _safeKeyHandle = SafeKeyHandle.InvalidHandle;
 
            if (IsPublic(parameters)) {
                // Use our CRYPT_VERIFYCONTEXT handle, CRYPT_EXPORTABLE is not applicable to public only keys, so pass false 
                Utils._ImportKey(Utils.StaticDssProvHandle, Constants.CALG_DSS_SIGN, (CspProviderFlags) 0, dsaCspObject, ref _safeKeyHandle); 
            } else {
                KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); 
                KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Import);
                kp.AccessEntries.Add(entry);
                kp.Demand();
                if (_safeProvHandle == null) 
                    _safeProvHandle = Utils.CreateProvHandle(_parameters, _randomKeyContainer);
                // Now, import the key into the CSP; _ImportKey will check for failures. 
                Utils._ImportKey(_safeProvHandle, Constants.CALG_DSS_SIGN, _parameters.Flags, dsaCspObject, ref _safeKeyHandle); 
            }
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        [System.Runtime.InteropServices.ComVisible(false)]
        public void ImportCspBlob (byte[] keyBlob) { 
            Utils.ImportCspBlobHelper(CspAlgorithmType.Dss, keyBlob, IsPublic(keyBlob), ref _parameters, _randomKeyContainer, ref _safeProvHandle, ref _safeKeyHandle);
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public byte[] SignData(Stream inputStream) { 
            byte[] hashVal = _sha1.ComputeHash(inputStream);
            return SignHash(hashVal, null);
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public byte[] SignData(byte[] buffer) { 
            byte[] hashVal = _sha1.ComputeHash(buffer); 
            return SignHash(hashVal, null);
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        public byte[] SignData(byte[] buffer, int offset, int count) {
            byte[] hashVal = _sha1.ComputeHash(buffer, offset, count); 
            return SignHash(hashVal, null);
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public bool VerifyData(byte[] rgbData, byte[] rgbSignature) { 
            byte[] hashVal = _sha1.ComputeHash(rgbData);
            return VerifyHash(hashVal, null, rgbSignature);
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        override public byte[] CreateSignature(byte[] rgbHash) { 
            return SignHash(rgbHash, null); 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        override public bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) {
            return VerifyHash(rgbHash, null, rgbSignature);
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public byte[] SignHash(byte[] rgbHash, string str) { 
            if (rgbHash == null)
                throw new ArgumentNullException("rgbHash"); 
            Contract.EndContractBlock();
            if (PublicOnly)
                throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_NoPrivateKey"));
 
            int calgHash = X509Utils.OidToAlgId(str);
            if (rgbHash.Length != _sha1.HashSize / 8) 
                throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidHashSize", "SHA1", _sha1.HashSize / 8)); 

            GetKeyPair(); 
            if (!CspKeyContainerInfo.RandomlyGenerated) {
                KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
                KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Sign);
                kp.AccessEntries.Add(entry); 
                kp.Demand();
            } 
            return Utils.SignValue(_safeKeyHandle, _parameters.KeyNumber, Constants.CALG_DSS_SIGN, calgHash, rgbHash); 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public bool VerifyHash(byte[] rgbHash, string str, byte[] rgbSignature) {
            if (rgbHash == null)
                throw new ArgumentNullException("rgbHash"); 
            if (rgbSignature == null)
                throw new ArgumentNullException("rgbSignature"); 
            Contract.EndContractBlock(); 

            int calgHash = X509Utils.OidToAlgId(str); 
            if (rgbHash.Length != _sha1.HashSize / 8)
                throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidHashSize", "SHA1", _sha1.HashSize / 8));

            GetKeyPair(); 
            return Utils.VerifySign(_safeKeyHandle, Constants.CALG_DSS_SIGN, calgHash, rgbHash, rgbSignature);
        } 
 
        //
        // private static methods 
        //

        private static DSAParameters DSAObjectToStruct (DSACspObject dsaCspObject) {
            DSAParameters dsaParams = new DSAParameters(); 
            dsaParams.P = dsaCspObject.P;
            dsaParams.Q = dsaCspObject.Q; 
            dsaParams.G = dsaCspObject.G; 
            dsaParams.Y = dsaCspObject.Y;
            dsaParams.J = dsaCspObject.J; 
            dsaParams.X = dsaCspObject.X;
            dsaParams.Seed = dsaCspObject.Seed;
            dsaParams.Counter = dsaCspObject.Counter;
            return dsaParams; 
        }
 
        private static DSACspObject DSAStructToObject (DSAParameters dsaParams) { 
            DSACspObject dsaCspObject = new DSACspObject();
            dsaCspObject.P = dsaParams.P; 
            dsaCspObject.Q = dsaParams.Q;
            dsaCspObject.G = dsaParams.G;
            dsaCspObject.Y = dsaParams.Y;
            dsaCspObject.J = dsaParams.J; 
            dsaCspObject.X = dsaParams.X;
            dsaCspObject.Seed = dsaParams.Seed; 
            dsaCspObject.Counter = dsaParams.Counter; 
            return dsaCspObject;
        } 

        private static bool IsPublic (DSAParameters dsaParams) {
            return (dsaParams.X == null);
        } 

        // find whether a DSS key blob is public. 
        private static bool IsPublic (byte[] keyBlob) { 
            if (keyBlob == null)
                throw new ArgumentNullException("keyBlob"); 
            Contract.EndContractBlock();

            // The CAPI DSS public key representation consists of the following sequence:
            //  - BLOBHEADER 
            //  - DSSPUBKEY
            //  - rgbP[cbKey] 
            //  - rgbQ[20] 
            //  - rgbG[cbKey]
            //  - rgbY[cbKey] 
            //  - DSSSEED

            // The first should be PUBLICKEYBLOB and magic should be DSS_MAGIC "DSS1" or DSS_PUB_MAGIC_VER3 "DSS3"
            if (keyBlob[0] != Constants.PUBLICKEYBLOB) 
                return false;
 
            if ((keyBlob[11] != 0x31 && keyBlob[11] != 0x33) || keyBlob[10] != 0x53 || keyBlob[9] != 0x53 || keyBlob[8] != 0x44) 
                return false;
 
            return true;
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK