internal static unsafe X509Certificate2 CreateDummyCertificate(CspParameters parameters) { System.Security.Cryptography.SafeCertContextHandle invalidHandle = System.Security.Cryptography.SafeCertContextHandle.InvalidHandle; SafeCryptProvHandle hCryptProv = SafeCryptProvHandle.InvalidHandle; uint dwFlags = 0U; if ((parameters.Flags & CspProviderFlags.UseMachineKeyStore) != CspProviderFlags.NoFlags) { dwFlags |= 32U; } if ((parameters.Flags & CspProviderFlags.UseDefaultKeyContainer) != CspProviderFlags.NoFlags) { dwFlags |= 4026531840U; } if ((parameters.Flags & CspProviderFlags.NoPrompt) != CspProviderFlags.NoFlags) { dwFlags |= 64U; } if (!CAPI.CryptAcquireContext(ref hCryptProv, parameters.KeyContainerName, parameters.ProviderName, (uint)parameters.ProviderType, dwFlags)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } CAPI.CRYPT_KEY_PROV_INFO cryptKeyProvInfo = new CAPI.CRYPT_KEY_PROV_INFO(); cryptKeyProvInfo.pwszProvName = parameters.ProviderName; cryptKeyProvInfo.pwszContainerName = parameters.KeyContainerName; cryptKeyProvInfo.dwProvType = (uint)parameters.ProviderType; cryptKeyProvInfo.dwKeySpec = (uint)parameters.KeyNumber; cryptKeyProvInfo.dwFlags = (parameters.Flags & CspProviderFlags.UseMachineKeyStore) == CspProviderFlags.UseMachineKeyStore ? 32U : 0U; SafeLocalAllocHandle localAllocHandle1 = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_KEY_PROV_INFO)))); Marshal.StructureToPtr((object)cryptKeyProvInfo, localAllocHandle1.DangerousGetHandle(), false); CAPI.CRYPT_ALGORITHM_IDENTIFIER algorithmIdentifier = new CAPI.CRYPT_ALGORITHM_IDENTIFIER(); algorithmIdentifier.pszObjId = "1.3.14.3.2.29"; SafeLocalAllocHandle localAllocHandle2 = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER)))); Marshal.StructureToPtr((object)algorithmIdentifier, localAllocHandle2.DangerousGetHandle(), false); X500DistinguishedName distinguishedName = new X500DistinguishedName("cn=CMS Signer Dummy Certificate"); System.Security.Cryptography.SafeCertContextHandle selfSignCertificate; fixed(byte *numPtr = distinguishedName.RawData) selfSignCertificate = CAPI.CAPIUnsafe.CertCreateSelfSignCertificate(hCryptProv, new IntPtr((void *)&new CAPI.CRYPTOAPI_BLOB() { cbData = (uint)distinguishedName.RawData.Length, pbData = new IntPtr((void *)numPtr) }), 1U, localAllocHandle1.DangerousGetHandle(), localAllocHandle2.DangerousGetHandle(), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); Marshal.DestroyStructure(localAllocHandle1.DangerousGetHandle(), typeof(CAPI.CRYPT_KEY_PROV_INFO)); localAllocHandle1.Dispose(); Marshal.DestroyStructure(localAllocHandle2.DangerousGetHandle(), typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER)); localAllocHandle2.Dispose(); if (selfSignCertificate == null || selfSignCertificate.IsInvalid) { throw new CryptographicException(Marshal.GetLastWin32Error()); } X509Certificate2 x509Certificate2 = new X509Certificate2(selfSignCertificate.DangerousGetHandle()); selfSignCertificate.Dispose(); return(x509Certificate2); }
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 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 > 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(); }
internal CMSG_SIGNER_ENCODE_INFO(int size) { this.cbSize = (uint)size; this.pCertInfo = IntPtr.Zero; this.hCryptProv = IntPtr.Zero; this.dwKeySpec = 0U; this.HashAlgorithm = new CAPI.CRYPT_ALGORITHM_IDENTIFIER(); this.pvHashAuxInfo = IntPtr.Zero; this.cAuthAttr = 0U; this.rgAuthAttr = IntPtr.Zero; this.cUnauthAttr = 0U; this.rgUnauthAttr = IntPtr.Zero; this.SignerId = new CAPI.CERT_ID(); this.HashEncryptionAlgorithm = new CAPI.CRYPT_ALGORITHM_IDENTIFIER(); this.pvHashEncryptionAuxInfo = IntPtr.Zero; }
internal CMSG_ENVELOPED_ENCODE_INFO(int size) { this.cbSize = (uint)size; this.hCryptProv = IntPtr.Zero; this.ContentEncryptionAlgorithm = new CAPI.CRYPT_ALGORITHM_IDENTIFIER(); this.pvEncryptionAuxInfo = IntPtr.Zero; this.cRecipients = 0U; this.rgpRecipients = IntPtr.Zero; this.rgCmsRecipients = IntPtr.Zero; this.cCertEncoded = 0U; this.rgCertEncoded = IntPtr.Zero; this.cCrlEncoded = 0U; this.rgCrlEncoded = IntPtr.Zero; this.cAttrCertEncoded = 0U; this.rgAttrCertEncoded = IntPtr.Zero; this.cUnprotectedAttr = 0U; this.rgUnprotectedAttr = IntPtr.Zero; }