Create() public static method

Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm.
public static Create ( ) : ECDsa
return ECDsa
Beispiel #1
0
        public static object?CreateFromName(string name, params object?[]?args)
        {
            ArgumentNullException.ThrowIfNull(name);

#if BROWSER
            switch (name)
            {
#pragma warning disable SYSLIB0021 // Obsolete: derived cryptographic types
            // hardcode mapping for SHA* and HMAC* algorithm names from https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptoconfig?view=net-5.0#remarks
            case "SHA":
            case "SHA1":
            case "System.Security.Cryptography.SHA1":
                return(new SHA1Managed());

            case "SHA256":
            case "SHA-256":
            case "System.Security.Cryptography.SHA256":
                return(new SHA256Managed());

            case "SHA384":
            case "SHA-384":
            case "System.Security.Cryptography.SHA384":
                return(new SHA384Managed());

            case "SHA512":
            case "SHA-512":
            case "System.Security.Cryptography.SHA512":
                return(new SHA512Managed());

#pragma warning restore SYSLIB0021

            case "System.Security.Cryptography.HMAC":
            case "HMACSHA1":
            case "System.Security.Cryptography.HMACSHA1":
            case "System.Security.Cryptography.KeyedHashAlgorithm":
                return(new HMACSHA1());

            case "HMACSHA256":
            case "System.Security.Cryptography.HMACSHA256":
                return(new HMACSHA256());

            case "HMACSHA384":
            case "System.Security.Cryptography.HMACSHA384":
                return(new HMACSHA384());

            case "HMACSHA512":
            case "System.Security.Cryptography.HMACSHA512":
                return(new HMACSHA512());

#pragma warning disable SYSLIB0021 // Obsolete: derived cryptographic types
            case "AES":
            case "System.Security.Cryptography.AesCryptoServiceProvider":
                return(new AesCryptoServiceProvider());

            case "AesManaged":
            case "System.Security.Cryptography.AesManaged":
                return(new AesManaged());

            case "Rijndael":
            case "System.Security.Cryptography.Rijndael":
#pragma warning disable SYSLIB0022 // Rijndael types are obsolete
                return(new RijndaelManaged());

#pragma warning restore SYSLIB0022
#pragma warning restore SYSLIB0021
            }

            return(null);
#else
            // Check to see if we have an application defined mapping
            appNameHT.TryGetValue(name, out Type? retvalType);

            // We allow the default table to Types and Strings
            // Types get used for types in .Algorithms assembly.
            // strings get used for delay-loaded stuff in other assemblies such as .Csp.
            if (retvalType == null && DefaultNameHT.TryGetValue(name, out object?retvalObj))
            {
                retvalType = retvalObj as Type;

                if (retvalType == null)
                {
                    if (retvalObj is string retvalString)
                    {
                        retvalType = Type.GetType(retvalString, false, false);
                        if (retvalType != null && !retvalType.IsVisible)
                        {
                            retvalType = null;
                        }

                        if (retvalType != null)
                        {
                            // Add entry to the appNameHT, which makes subsequent calls much faster.
                            appNameHT[name] = retvalType;
                        }
                    }
                    else
                    {
                        Debug.Fail("Unsupported Dictionary value:" + retvalObj.ToString());
                    }
                }
            }

            // Special case asking for "ECDsa" since the default map from .NET Framework uses
            // a Windows-only type.
            if (retvalType == null &&
                (args == null || args.Length == 1) &&
                name == ECDsaIdentifier)
            {
                return(ECDsa.Create());
            }

            // Maybe they gave us a classname.
            if (retvalType == null)
            {
                retvalType = Type.GetType(name, false, false);
                if (retvalType != null && !retvalType.IsVisible)
                {
                    retvalType = null;
                }
            }

            // Still null? Then we didn't find it.
            if (retvalType == null)
            {
                return(null);
            }

            // Locate all constructors.
            MethodBase[] cons = retvalType.GetConstructors(ConstructorDefault);
            if (cons == null)
            {
                return(null);
            }

            if (args == null)
            {
                args = Array.Empty <object>();
            }

            List <MethodBase> candidates = new List <MethodBase>();
            for (int i = 0; i < cons.Length; i++)
            {
                MethodBase con = cons[i];
                if (con.GetParameters().Length == args.Length)
                {
                    candidates.Add(con);
                }
            }

            if (candidates.Count == 0)
            {
                return(null);
            }

            cons = candidates.ToArray();

            // Bind to matching ctor.
            ConstructorInfo?rci = Type.DefaultBinder.BindToMethod(
                ConstructorDefault,
                cons,
                ref args,
                null,
                null,
                null,
                out object?state) as ConstructorInfo;

            // Check for ctor we don't like (non-existent, delegate or decorated with declarative linktime demand).
            if (rci == null || typeof(Delegate).IsAssignableFrom(rci.DeclaringType))
            {
                return(null);
            }

            // Ctor invoke and allocation.
            object retval = rci.Invoke(ConstructorDefault, Type.DefaultBinder, args, null);

            // Reset any parameter re-ordering performed by the binder.
            if (state != null)
            {
                Type.DefaultBinder.ReorderArgumentArray(ref args, state);
            }

            return(retval);
#endif
        }
Beispiel #2
0
        public static object?CreateFromName(string name, params object?[]?args)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            // Check to see if we have an application defined mapping
            appNameHT.TryGetValue(name, out Type? retvalType);

            // We allow the default table to Types and Strings
            // Types get used for types in .Algorithms assembly.
            // strings get used for delay-loaded stuff in other assemblies such as .Csp.
            if (retvalType == null && DefaultNameHT.TryGetValue(name, out object?retvalObj))
            {
                retvalType = retvalObj as Type;

                if (retvalType == null)
                {
                    if (retvalObj is string retvalString)
                    {
                        retvalType = Type.GetType(retvalString, false, false);
                        if (retvalType != null && !retvalType.IsVisible)
                        {
                            retvalType = null;
                        }

                        if (retvalType != null)
                        {
                            // Add entry to the appNameHT, which makes subsequent calls much faster.
                            appNameHT[name] = retvalType;
                        }
                    }
                    else
                    {
                        Debug.Fail("Unsupported Dictionary value:" + retvalObj.ToString());
                    }
                }
            }

            // Special case asking for "ECDsa" since the default map from .NET Framework uses
            // a Windows-only type.
            if (retvalType == null &&
                (args == null || args.Length == 1) &&
                name == ECDsaIdentifier)
            {
                return(ECDsa.Create());
            }

            // Maybe they gave us a classname.
            if (retvalType == null)
            {
                retvalType = Type.GetType(name, false, false);
                if (retvalType != null && !retvalType.IsVisible)
                {
                    retvalType = null;
                }
            }

            // Still null? Then we didn't find it.
            if (retvalType == null)
            {
                return(null);
            }

            // Locate all constructors.
            MethodBase[] cons = retvalType.GetConstructors(ConstructorDefault);
            if (cons == null)
            {
                return(null);
            }

            if (args == null)
            {
                args = Array.Empty <object>();
            }

            List <MethodBase> candidates = new List <MethodBase>();

            for (int i = 0; i < cons.Length; i++)
            {
                MethodBase con = cons[i];
                if (con.GetParameters().Length == args.Length)
                {
                    candidates.Add(con);
                }
            }

            if (candidates.Count == 0)
            {
                return(null);
            }

            cons = candidates.ToArray();

            // Bind to matching ctor.
            ConstructorInfo?rci = Type.DefaultBinder.BindToMethod(
                ConstructorDefault,
                cons,
                ref args,
                null,
                null,
                null,
                out object?state) as ConstructorInfo;

            // Check for ctor we don't like (non-existent, delegate or decorated with declarative linktime demand).
            if (rci == null || typeof(Delegate).IsAssignableFrom(rci.DeclaringType))
            {
                return(null);
            }

            // Ctor invoke and allocation.
            object retval = rci.Invoke(ConstructorDefault, Type.DefaultBinder, args, null);

            // Reset any parameter re-ordering performed by the binder.
            if (state != null)
            {
                Type.DefaultBinder.ReorderArgumentArray(ref args, state);
            }

            return(retval);
        }
Beispiel #3
0
        /// <summary>
        ///     Read the x and y components of the public key
        /// </summary>
        private static void ReadPublicKey(XPathNavigator navigator, ref ECParameters parameters)
        {
            Contract.Requires(navigator != null);

            if (navigator.NamespaceURI != Namespace)
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_UnexpectedXmlNamespace,
                                                         navigator.NamespaceURI,
                                                         Namespace));
            }

            if (navigator.Name != PublicKeyRoot)
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_MissingPublicKey));
            }

            // First get the x parameter
            if (!navigator.MoveToFirstChild() || navigator.Name != XElement)
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_MissingPublicKey));
            }
            if (!navigator.MoveToFirstAttribute() || navigator.Name != ValueAttribute || String.IsNullOrEmpty(navigator.Value))
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_MissingPublicKey));
            }

            BigInteger x = BigInteger.Parse(navigator.Value, CultureInfo.InvariantCulture);

            navigator.MoveToParent();

            // Then the y parameter
            if (!navigator.MoveToNext(XPathNodeType.Element) || navigator.Name != YElement)
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_MissingPublicKey));
            }
            if (!navigator.MoveToFirstAttribute() || navigator.Name != ValueAttribute || String.IsNullOrEmpty(navigator.Value))
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_MissingPublicKey));
            }

            BigInteger y = BigInteger.Parse(navigator.Value, CultureInfo.InvariantCulture);

            byte[] xBytes = x.ToByteArray();
            byte[] yBytes = y.ToByteArray();

            int xLen = xBytes.Length;
            int yLen = yBytes.Length;

            // If the last byte of X is 0x00 that's a padding byte by BigInteger to indicate X is
            // a positive number with the highest bit in the most significant byte set. We can't count
            // that in the length of the number.
            if (xLen > 0 && xBytes[xLen - 1] == 0)
            {
                xLen--;
            }

            // Ditto for Y.
            if (yLen > 0 && yBytes[yLen - 1] == 0)
            {
                yLen--;
            }

            // Q.X and Q.Y have to be the same length.  They ultimately have to be the right length for the curve,
            // but that requires more knowledge than we have. So we'll ask the system. If it doesn't know, just make
            // them match each other.
            int requiredLength = Math.Max(xLen, yLen);

            try {
                using (ECDsa ecdsa = ECDsa.Create(parameters.Curve)) {
                    // Convert the bit value of keysize to a byte value.
                    // EC curves can have non-mod-8 keysizes (e.g. 521), so the +7 is really necessary.
                    int curveLength = (ecdsa.KeySize + 7) / 8;

                    // We could just use this answer, but if the user has formatted the input to be
                    // too long, maybe they know something we don't.
                    requiredLength = Math.Max(requiredLength, curveLength);
                }
            }
            catch (ArgumentException) { /* Curve had invalid data, like an empty OID */ }
            catch (CryptographicException) { /* The system failed to generate a key for the curve */ }
            catch (NotSupportedException) { /* An unknown curve type was requested */ }

            // There is a chance that the curve is known to Windows but not allowed for ECDH
            // (curve25519 is known to be in this state). Since RFC4050 is officially only
            // concerned with ECDSA, and the only known example of this problem does not have
            // an OID, it is not worth trying to generate the curve under ECDH as a fallback.

            // Since BigInteger does Little Endian and Array.Resize maintains indexes when growing,
            // just Array.Resize, then Array.Reverse. We could optimize this to be 1N instead of 2N,
            // but this isn't a very hot codepath, so use tried-and-true methods.
            Array.Resize(ref xBytes, requiredLength);
            Array.Resize(ref yBytes, requiredLength);
            Array.Reverse(xBytes);
            Array.Reverse(yBytes);

            parameters.Q.X = xBytes;
            parameters.Q.Y = yBytes;
        }