예제 #1
0
        static AsymmetricAlgorithm GetAsymmetricAlgorithm(DsaPublicKeyParameters key)
        {
            var parameters = GetDSAParameters(key);

            parameters.Y = key.Y.ToByteArrayUnsigned();

#if NET45 || NET46 || NETSTANDARD2_0 || __MOBILE__
            var dsa = new DSACryptoServiceProvider();
#else
            var dsa = new DSACng();
#endif

            dsa.ImportParameters(parameters);

            return(dsa);
        }
예제 #2
0
        static AsymmetricAlgorithm GetAsymmetricAlgorithm(DsaPrivateKeyParameters key, DsaPublicKeyParameters pub)
        {
            var parameters = GetDSAParameters(key);

            parameters.X = key.X.ToByteArrayUnsigned();

            if (pub != null)
            {
                parameters.Y = pub.Y.ToByteArrayUnsigned();
            }

#if NET45 || NET46 || __MOBILE__
            var dsa = new DSACryptoServiceProvider();
#else
            var dsa = new DSACng();
#endif

            dsa.ImportParameters(parameters);

            return(dsa);
        }
예제 #3
0
        public ICertificatePal CopyWithPrivateKey(DSA dsa)
        {
            DSACng          dsaCng = dsa as DSACng;
            ICertificatePal clone  = null;

            if (dsaCng != null)
            {
                clone = CopyWithPersistedCngKey(dsaCng.Key);

                if (clone != null)
                {
                    return(clone);
                }
            }

            DSACryptoServiceProvider dsaCsp = dsa as DSACryptoServiceProvider;

            if (dsaCsp != null)
            {
                clone = CopyWithPersistedCapiKey(dsaCsp.CspKeyContainerInfo);

                if (clone != null)
                {
                    return(clone);
                }
            }

            DSAParameters privateParameters = dsa.ExportParameters(true);

            using (PinAndClear.Track(privateParameters.X))
                using (DSACng clonedKey = new DSACng())
                {
                    clonedKey.ImportParameters(privateParameters);

                    return(CopyWithEphemeralKey(clonedKey.Key));
                }
        }
예제 #4
0
        public static DSA GetDSAPublicKey(this X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }

            if (!IsDSA(certificate))
            {
                return(null);
            }

            unsafe
            {
                DSAParameters dp = new DSAParameters();

                SafeLocalAllocHandle dssKeyLocalAlloc = null;
                try
                {
                    byte[] encodedPublicKey = certificate.PublicKey.EncodedKeyValue.RawData;
                    uint   cbDSSKey;
                    if (!CapiNative.DecodeObject((IntPtr)(CapiNative.X509_DSS_PUBLICKEY), encodedPublicKey, out dssKeyLocalAlloc, out cbDSSKey))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (cbDSSKey < Marshal.SizeOf(typeof(CapiNative.CRYPTOAPI_BLOB)))
                    {
                        throw new CryptographicException();
                    }

                    CapiNative.CRYPTOAPI_BLOB *pDssKeyBlob = (CapiNative.CRYPTOAPI_BLOB *)(dssKeyLocalAlloc.DangerousGetHandle());
                    dp.Y = ToBigEndianByteArray(*pDssKeyBlob);
                }
                finally
                {
                    if (dssKeyLocalAlloc != null)
                    {
                        dssKeyLocalAlloc.Dispose();
                        dssKeyLocalAlloc = null;
                    }
                }

                SafeLocalAllocHandle dssParametersLocalHandle = null;
                try
                {
                    byte[] encodedKeyAlgorithmParameters = certificate.GetKeyAlgorithmParameters();
                    uint   cbDSSParams;
                    if (!CapiNative.DecodeObject((IntPtr)(CapiNative.X509_DSS_PARAMETERS), encodedKeyAlgorithmParameters, out dssParametersLocalHandle, out cbDSSParams))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (cbDSSParams < Marshal.SizeOf(typeof(CapiNative.CERT_DSS_PARAMETERS)))
                    {
                        throw new CryptographicException();
                    }

                    CapiNative.CERT_DSS_PARAMETERS *pDssParameters = (CapiNative.CERT_DSS_PARAMETERS *)(dssParametersLocalHandle.DangerousGetHandle());
                    dp.P = ToBigEndianByteArray(pDssParameters->p);
                    dp.Q = ToBigEndianByteArray(pDssParameters->q);
                    dp.G = ToBigEndianByteArray(pDssParameters->g);
                }
                finally
                {
                    if (dssParametersLocalHandle != null)
                    {
                        dssParametersLocalHandle.Dispose();
                        dssParametersLocalHandle = null;
                    }
                }

                DSACng dsaCng = new DSACng();
                dsaCng.ImportParameters(dp);
                return(dsaCng);
            }
        }
예제 #5
0
        public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, DSA privateKey)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }
            if (privateKey == null)
            {
                throw new ArgumentNullException(nameof(privateKey));
            }

            if (certificate.HasPrivateKey)
            {
                throw new InvalidOperationException(SR.GetString(SR.Cryptography_Cert_AlreadyHasPrivateKey));
            }

            using (DSA publicKey = GetDSAPublicKey(certificate))
            {
                if (publicKey == null)
                {
                    throw new ArgumentException(SR.GetString(SR.Cryptography_PrivateKey_WrongAlgorithm));
                }

                DSAParameters currentParameters = publicKey.ExportParameters(false);
                DSAParameters newParameters     = privateKey.ExportParameters(false);

                if (!currentParameters.G.SequenceEqual(newParameters.G) ||
                    !currentParameters.P.SequenceEqual(newParameters.P) ||
                    !currentParameters.Q.SequenceEqual(newParameters.Q) ||
                    !currentParameters.Y.SequenceEqual(newParameters.Y))
                {
                    throw new ArgumentException(SR.GetString(SR.Cryptography_PrivateKey_DoesNotMatch), nameof(privateKey));
                }
            }

            DSACng           dsaCng  = privateKey as DSACng;
            X509Certificate2 newCert = null;

            if (dsaCng != null)
            {
                newCert = CertificateExtensionsCommon.CopyWithPersistedCngKey(certificate, dsaCng.Key);
            }

            if (newCert == null)
            {
                DSACryptoServiceProvider dsaCsp = privateKey as DSACryptoServiceProvider;

                if (dsaCsp != null)
                {
                    newCert = CertificateExtensionsCommon.CopyWithPersistedCapiKey(certificate, dsaCsp.CspKeyContainerInfo);
                }
            }

            if (newCert == null)
            {
                DSAParameters parameters = privateKey.ExportParameters(true);

                using (PinAndClear.Track(parameters.X))
                    using (dsaCng = new DSACng())
                    {
                        dsaCng.ImportParameters(parameters);

                        newCert = CertificateExtensionsCommon.CopyWithEphemeralCngKey(certificate, dsaCng.Key);
                    }
            }

            Debug.Assert(newCert != null);
            Debug.Assert(!ReferenceEquals(certificate, newCert));
            Debug.Assert(!certificate.HasPrivateKey);
            Debug.Assert(newCert.HasPrivateKey);
            return(newCert);
        }