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(); }
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(); }