Esempio n. 1
0
        internal AlgorithmIdentifier(CAPI.CRYPT_ALGORITHM_IDENTIFIER algorithmIdentifier)
        {
            int  keyLength      = 0;
            uint cbDecodedValue = 0U;
            SafeLocalAllocHandle decodedValue = SafeLocalAllocHandle.InvalidHandle;

            byte[] numArray = new byte[0];
            uint   num      = X509Utils.OidToAlgId(algorithmIdentifier.pszObjId);

            switch (num)
            {
            case 26114U:
                if (algorithmIdentifier.Parameters.cbData > 0U)
                {
                    if (!CAPI.DecodeObject(new IntPtr(41L), algorithmIdentifier.Parameters.pbData, algorithmIdentifier.Parameters.cbData, out decodedValue, out cbDecodedValue))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    CAPI.CRYPT_RC2_CBC_PARAMETERS rc2CbcParameters = (CAPI.CRYPT_RC2_CBC_PARAMETERS)Marshal.PtrToStructure(decodedValue.DangerousGetHandle(), typeof(CAPI.CRYPT_RC2_CBC_PARAMETERS));
                    switch (rc2CbcParameters.dwVersion)
                    {
                    case 52U:
                        keyLength = 56;
                        break;

                    case 58U:
                        keyLength = 128;
                        break;

                    case 160U:
                        keyLength = 40;
                        break;
                    }
                    if (rc2CbcParameters.fIV)
                    {
                        numArray = (byte[])rc2CbcParameters.rgbIV.Clone();
                        break;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }

            case 26625U:
            case 26113U:
            case 26115U:
                if (algorithmIdentifier.Parameters.cbData > 0U)
                {
                    if (!CAPI.DecodeObject(new IntPtr(25L), algorithmIdentifier.Parameters.pbData, algorithmIdentifier.Parameters.cbData, out decodedValue, out cbDecodedValue))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (cbDecodedValue > 0U)
                    {
                        if ((int)num == 26625)
                        {
                            CAPI.CRYPTOAPI_BLOB cryptoapiBlob = (CAPI.CRYPTOAPI_BLOB)Marshal.PtrToStructure(decodedValue.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB));
                            if (cryptoapiBlob.cbData > 0U)
                            {
                                numArray = new byte[(IntPtr)cryptoapiBlob.cbData];
                                Marshal.Copy(cryptoapiBlob.pbData, numArray, 0, numArray.Length);
                            }
                        }
                        else
                        {
                            numArray = new byte[(IntPtr)cbDecodedValue];
                            Marshal.Copy(decodedValue.DangerousGetHandle(), numArray, 0, numArray.Length);
                        }
                    }
                }
                keyLength = (int)num != 26625 ? ((int)num != 26113 ? 192 : 64) : 128 - numArray.Length * 8;
                break;

            default:
                if (algorithmIdentifier.Parameters.cbData > 0U)
                {
                    numArray = new byte[(IntPtr)algorithmIdentifier.Parameters.cbData];
                    Marshal.Copy(algorithmIdentifier.Parameters.pbData, numArray, 0, numArray.Length);
                    break;
                }
                else
                {
                    break;
                }
            }
            this.Reset(new Oid(algorithmIdentifier.pszObjId), keyLength, numArray);
            decodedValue.Dispose();
        }
Esempio n. 2
0
        internal AlgorithmIdentifier(CAPI.CRYPT_ALGORITHM_IDENTIFIER algorithmIdentifier)
        {
            int  keyLength    = 0;
            uint cbParameters = 0;
            SafeLocalAllocHandle pbParameters = SafeLocalAllocHandle.InvalidHandle;

            byte[] parameters = new byte[0];

            uint algId = X509Utils.OidToAlgId(algorithmIdentifier.pszObjId);

            if (algId == CAPI.CALG_RC2)
            {
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    if (!CAPI.DecodeObject(new IntPtr(CAPI.PKCS_RC2_CBC_PARAMETERS),
                                           algorithmIdentifier.Parameters.pbData,
                                           algorithmIdentifier.Parameters.cbData,
                                           out pbParameters,
                                           out cbParameters))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    CAPI.CRYPT_RC2_CBC_PARAMETERS rc2Parameters = (CAPI.CRYPT_RC2_CBC_PARAMETERS)Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPT_RC2_CBC_PARAMETERS));
                    switch (rc2Parameters.dwVersion)
                    {
                    case CAPI.CRYPT_RC2_40BIT_VERSION:
                        keyLength = 40;
                        break;

                    case CAPI.CRYPT_RC2_56BIT_VERSION:
                        keyLength = 56;
                        break;

                    case CAPI.CRYPT_RC2_128BIT_VERSION:
                        keyLength = 128;
                        break;
                    }
                    // Retrieve IV if available.
                    if (rc2Parameters.fIV)
                    {
                        parameters = (byte[])rc2Parameters.rgbIV.Clone();
                    }
                }
            }
            else if (algId == CAPI.CALG_RC4 || algId == CAPI.CALG_DES || algId == CAPI.CALG_3DES)
            {
                // Retrieve the IV if available. For non RC2, the parameter contains the IV
                // (for RC4 the IV is really the salt). There are (128 - KeyLength) / 8
                // bytes of RC4 salt.
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    if (!CAPI.DecodeObject(new IntPtr(CAPI.X509_OCTET_STRING),
                                           algorithmIdentifier.Parameters.pbData,
                                           algorithmIdentifier.Parameters.cbData,
                                           out pbParameters,
                                           out cbParameters))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    if (cbParameters > Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)))
                    {
                        CAPI.CRYPTOAPI_BLOB blob = (CAPI.CRYPTOAPI_BLOB)Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB));

                        if (algId == CAPI.CALG_RC4)
                        {
                            if (blob.cbData > 0)
                            {
                                parameters = new byte[blob.cbData];
                                Marshal.Copy(blob.pbData, parameters, 0, parameters.Length);
                            }
                        }
                        else
                        {
                            // This should be the same as the RC4 code, but for compatibility
                            // * Allocate an array as big as the CRYPTOAPI_BLOB
                            // * Copy in the cbData value
                            // * Copy in the (pbData) value
                            //
                            // But don't copy in the pbData pointer value (or, rather, clear it out),
                            // among other things it makes decoding the same contents into two
                            // different EnvelopedCms objects say the parameters were different.
                            parameters = new byte[cbParameters];
                            Marshal.Copy(pbParameters.DangerousGetHandle(), parameters, 0, parameters.Length);
                            Array.Clear(parameters, sizeof(uint), (int)(parameters.Length - blob.cbData - sizeof(uint)));
                        }
                    }
                }

                // Determine key length.
                if (algId == CAPI.CALG_RC4)
                {
                    // For RC4, keyLength = 128 - (salt length * 8).
                    keyLength = 128 - ((int)parameters.Length * 8);
                }
                else if (algId == CAPI.CALG_DES)
                {
                    // DES key length is fixed at 64 (or 56 without the parity bits).
                    keyLength = 64;
                }
                else
                {
                    // 3DES key length is fixed at 192 (or 168 without the parity bits).
                    keyLength = 192;
                }
            }
            else
            {
                // Everything else, don't decode it as CAPI may not expose or know how.
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    parameters = new byte[algorithmIdentifier.Parameters.cbData];
                    Marshal.Copy(algorithmIdentifier.Parameters.pbData, parameters, 0, parameters.Length);
                }
            }

            Reset(Oid.FromOidValue(algorithmIdentifier.pszObjId, OidGroup.All), keyLength, parameters);
            pbParameters.Dispose();
        }
        internal AlgorithmIdentifier(CAPI.CRYPT_ALGORITHM_IDENTIFIER algorithmIdentifier)
        {
            int  keyLength    = 0;
            uint cbParameters = 0;
            SafeLocalAllocHandle pbParameters = SafeLocalAllocHandle.InvalidHandle;

            byte[] parameters = new byte[0];

            uint algId = X509Utils.OidToAlgId(algorithmIdentifier.pszObjId);

            if (algId == CAPI.CALG_RC2)
            {
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    if (!CAPI.DecodeObject(new IntPtr(CAPI.PKCS_RC2_CBC_PARAMETERS),
                                           algorithmIdentifier.Parameters.pbData,
                                           algorithmIdentifier.Parameters.cbData,
                                           out pbParameters,
                                           out cbParameters))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    CAPI.CRYPT_RC2_CBC_PARAMETERS rc2Parameters = (CAPI.CRYPT_RC2_CBC_PARAMETERS)Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPT_RC2_CBC_PARAMETERS));
                    switch (rc2Parameters.dwVersion)
                    {
                    case CAPI.CRYPT_RC2_40BIT_VERSION:
                        keyLength = 40;
                        break;

                    case CAPI.CRYPT_RC2_56BIT_VERSION:
                        keyLength = 56;
                        break;

                    case CAPI.CRYPT_RC2_128BIT_VERSION:
                        keyLength = 128;
                        break;
                    }
                    // Retrieve IV if available.
                    if (rc2Parameters.fIV)
                    {
                        parameters = (byte[])rc2Parameters.rgbIV.Clone();
                    }
                }
            }
            else if (algId == CAPI.CALG_RC4 || algId == CAPI.CALG_DES || algId == CAPI.CALG_3DES)
            {
                // Retrieve the IV if available. For non RC2, the parameter contains the IV
                // (for RC4 the IV is really the salt). There are (128 - KeyLength) / 8
                // bytes of RC4 salt.
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    if (!CAPI.DecodeObject(new IntPtr(CAPI.X509_OCTET_STRING),
                                           algorithmIdentifier.Parameters.pbData,
                                           algorithmIdentifier.Parameters.cbData,
                                           out pbParameters,
                                           out cbParameters))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    if (cbParameters > 0)
                    {
                        if (algId == CAPI.CALG_RC4)
                        {
                            CAPI.CRYPTOAPI_BLOB saltBlob = (CAPI.CRYPTOAPI_BLOB)Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB));
                            if (saltBlob.cbData > 0)
                            {
                                parameters = new byte[saltBlob.cbData];
                                Marshal.Copy(saltBlob.pbData, parameters, 0, parameters.Length);
                            }
                        }
                        else
                        {
                            parameters = new byte[cbParameters];
                            Marshal.Copy(pbParameters.DangerousGetHandle(), parameters, 0, parameters.Length);
                        }
                    }
                }

                // Determine key length.
                if (algId == CAPI.CALG_RC4)
                {
                    // For RC4, keyLength = 128 - (salt length * 8).
                    keyLength = 128 - ((int)parameters.Length * 8);
                }
                else if (algId == CAPI.CALG_DES)
                {
                    // DES key length is fixed at 64 (or 56 without the parity bits).
                    keyLength = 64;
                }
                else
                {
                    // 3DES key length is fixed at 192 (or 168 without the parity bits).
                    keyLength = 192;
                }
            }
            else
            {
                // Everything else, don't decode it as CAPI may not expose or know how.
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    parameters = new byte[algorithmIdentifier.Parameters.cbData];
                    Marshal.Copy(algorithmIdentifier.Parameters.pbData, parameters, 0, parameters.Length);
                }
            }

            Reset(Oid.FromOidValue(algorithmIdentifier.pszObjId, OidGroup.All), keyLength, parameters);
            pbParameters.Dispose();
        }