private static unsafe byte[] EncodeExtension(byte[] subjectKeyIdentifier) { if (subjectKeyIdentifier == null) { throw new ArgumentNullException("subjectKeyIdentifier"); } if (subjectKeyIdentifier.Length == 0) { throw new ArgumentException("subjectKeyIdentifier"); } byte[] encodedSubjectKeyIdentifier = null; fixed(byte *pb = subjectKeyIdentifier) { CAPI.CRYPTOAPI_BLOB pSubjectKeyIdentifier = new CAPI.CRYPTOAPI_BLOB(); pSubjectKeyIdentifier.pbData = new IntPtr(pb); pSubjectKeyIdentifier.cbData = (uint)subjectKeyIdentifier.Length; if (!CAPI.EncodeObject(CAPI.szOID_SUBJECT_KEY_IDENTIFIER, new IntPtr(&pSubjectKeyIdentifier), out encodedSubjectKeyIdentifier)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } return(encodedSubjectKeyIdentifier); }
private void DecodeExtension() { uint cbDecoded = 0; SafeLocalAllocHandle decoded = null; bool result = CAPI.DecodeObject(new IntPtr(CAPI.X509_KEY_USAGE), m_rawData, out decoded, out cbDecoded); if (result == false) { throw new CryptographicException(Marshal.GetLastWin32Error()); } CAPI.CRYPTOAPI_BLOB pKeyUsage = (CAPI.CRYPTOAPI_BLOB)Marshal.PtrToStructure(decoded.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB)); if (pKeyUsage.cbData > 4) { pKeyUsage.cbData = 4; } byte[] keyUsage = new byte[4]; if (pKeyUsage.pbData != IntPtr.Zero) { Marshal.Copy(pKeyUsage.pbData, keyUsage, 0, (int)pKeyUsage.cbData); } m_keyUsages = BitConverter.ToUInt32(keyUsage, 0); m_decoded = true; decoded.Dispose(); }
internal static unsafe byte[] EncodeOctetString(byte[] octets) { fixed(byte *numPtr = octets) { CAPI.CRYPTOAPI_BLOB cryptoapiBlob = new CAPI.CRYPTOAPI_BLOB(); cryptoapiBlob.cbData = (uint)octets.Length; cryptoapiBlob.pbData = new IntPtr((void *)numPtr); byte[] encodedData = new byte[0]; if (!CAPI.EncodeObject(new IntPtr(25L), new IntPtr((long)&cryptoapiBlob), out encodedData)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } else { return(encodedData); } } }
internal static string DecodeOctetString(byte[] encodedOctetString) { uint cbDecodedValue = 0U; SafeLocalAllocHandle decodedValue = (SafeLocalAllocHandle)null; if (!CAPI.DecodeObject(new IntPtr(25L), encodedOctetString, out decodedValue, out cbDecodedValue)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } if ((int)cbDecodedValue == 0) { return(string.Empty); } CAPI.CRYPTOAPI_BLOB cryptoapiBlob = (CAPI.CRYPTOAPI_BLOB)Marshal.PtrToStructure(decodedValue.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB)); if ((int)cryptoapiBlob.cbData == 0) { return(string.Empty); } string str = Marshal.PtrToStringUni(cryptoapiBlob.pbData); decodedValue.Dispose(); return(str); }
private void DecodeExtension() { uint cbDecoded = 0; SafeLocalAllocHandle decoded = null; SafeLocalAllocHandle pb = X509Utils.StringToAnsiPtr(CAPI.szOID_SUBJECT_KEY_IDENTIFIER); bool result = CAPI.DecodeObject(pb.DangerousGetHandle(), m_rawData, out decoded, out cbDecoded); if (!result) { throw new CryptographicException(Marshal.GetLastWin32Error()); } CAPI.CRYPTOAPI_BLOB pSubjectKeyIdentifier = (CAPI.CRYPTOAPI_BLOB)Marshal.PtrToStructure(decoded.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB)); byte[] hexArray = CAPI.BlobToByteArray(pSubjectKeyIdentifier); m_subjectKeyIdentifier = X509Utils.EncodeHexString(hexArray); m_decoded = true; decoded.Dispose(); pb.Dispose(); }
internal unsafe SubjectIdentifier(CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) { // If serial number is 0, then it is the special SKI encoding or NoSignature bool isSKIorHashOnly = true; byte *pb = (byte *)serialNumber.pbData; for (uint i = 0; i < serialNumber.cbData; i++) { if (*pb++ != (byte)0) { isSKIorHashOnly = false; break; } } if (isSKIorHashOnly) { byte[] issuerBytes = new byte[issuer.cbData]; Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length); X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes); if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0) { Reset(SubjectIdentifierType.NoSignature, null); return; } } if (isSKIorHashOnly) { // Decode disguised SKI in issuer field (See WinCrypt.h for more info). Note that some certificates may contain // an all-zero serial number but not be encoded with an szOID_KEYID_RDN. In order to allow use of signatures created // using these certificates, we will first try to find the szOID_KEYID_RDN, but if it does not exist, fall back to just // decoding the incoming issuer and serial number. m_type = SubjectIdentifierType.SubjectKeyIdentifier; m_value = String.Empty; uint cbCertNameInfo = 0; SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle; if (CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME), issuer.pbData, issuer.cbData, out pbCertNameInfo, out cbCertNameInfo)) { using (pbCertNameInfo) { checked { CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO)); for (uint i = 0; i < certNameInfo.cRDN; i++) { CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr((long)certNameInfo.rgRDN + (long)(i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN)); for (uint j = 0; j < certRdn.cRDNAttr; j++) { CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)(j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR)); if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0) { if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING) { byte[] ski = new byte[certRdnAttr.Value.cbData]; Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); return; } } } } } } } } CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial; IssuerAndSerial.Issuer = issuer; IssuerAndSerial.SerialNumber = serialNumber; X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial); Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial); }
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(); }
// // Constructors. // internal X500DistinguishedName(CAPI.CRYPTOAPI_BLOB encodedDistinguishedNameBlob) : base(new Oid(), encodedDistinguishedNameBlob) { }
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 CRYPT_OID_INFO(int size) { this.cbSize = (uint)size; this.pszOID = (string)null; this.pwszName = (string)null; this.dwGroupId = 0U; this.Algid = 0U; this.ExtraInfo = new CAPI.CRYPTOAPI_BLOB(); }
/// <summary> /// Protect /// </summary> public static byte[] Protect(byte[] userData, byte[] optionalEntropy, DataProtectionScope scope) { if (userData == null) throw new ArgumentNullException("userData"); GCHandle pbDataIn = new GCHandle(); GCHandle pOptionalEntropy = new GCHandle(); CAPI.CRYPTOAPI_BLOB blob = new CAPI.CRYPTOAPI_BLOB(); try { pbDataIn = GCHandle.Alloc(userData, GCHandleType.Pinned); CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB(); dataIn.cbData = (uint)userData.Length; dataIn.pbData = pbDataIn.AddrOfPinnedObject(); CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB(); if (optionalEntropy != null) { pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned); entropy.cbData = (uint)optionalEntropy.Length; entropy.pbData = pOptionalEntropy.AddrOfPinnedObject(); } uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN; if (scope == DataProtectionScope.LocalMachine) dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE; unsafe { if (!CAPI.CryptProtectData(new IntPtr(&dataIn), String.Empty, new IntPtr(&entropy), IntPtr.Zero, IntPtr.Zero, dwFlags, new IntPtr(&blob))) { int lastWin32Error = Marshal.GetLastWin32Error(); // One of the most common reasons that DPAPI operations fail is that the user // profile is not loaded (for instance in the case of impersonation or running in a // service. In those cases, throw an exception that provides more specific details // about what happened. if (CAPI.ErrorMayBeCausedByUnloadedProfile(lastWin32Error)) { throw new CryptographicException("Cryptography_DpApi_ProfileMayNotBeLoaded"); } else { throw new CryptographicException(lastWin32Error); } } } // In some cases, the API would fail due to OOM but simply return a null pointer. if (blob.pbData == IntPtr.Zero) throw new OutOfMemoryException(); byte[] encryptedData = new byte[(int)blob.cbData]; Marshal.Copy(blob.pbData, encryptedData, 0, encryptedData.Length); return encryptedData; } finally { if (pbDataIn.IsAllocated) pbDataIn.Free(); if (pOptionalEntropy.IsAllocated) pOptionalEntropy.Free(); if (blob.pbData != IntPtr.Zero) { CAPI.ZeroMemory(blob.pbData, blob.cbData); CAPI.LocalFree(blob.pbData); } } }
public static byte[] Unprotect(byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope) { if (encryptedData == null) { throw new ArgumentNullException("encryptedData"); } if (Environment.OSVersion.Platform == PlatformID.Win32Windows) { throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT")); } GCHandle pbDataIn = new GCHandle(); GCHandle pOptionalEntropy = new GCHandle(); CAPI.CRYPTOAPI_BLOB userData = new CAPI.CRYPTOAPI_BLOB(); RuntimeHelpers.PrepareConstrainedRegions(); try { pbDataIn = GCHandle.Alloc(encryptedData, GCHandleType.Pinned); CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB(); dataIn.cbData = (uint)encryptedData.Length; dataIn.pbData = pbDataIn.AddrOfPinnedObject(); CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB(); if (optionalEntropy != null) { pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned); entropy.cbData = (uint)optionalEntropy.Length; entropy.pbData = pOptionalEntropy.AddrOfPinnedObject(); } uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN; if (scope == DataProtectionScope.LocalMachine) { dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE; } unsafe { if (!CAPI.CryptUnprotectData(new IntPtr(&dataIn), IntPtr.Zero, new IntPtr(&entropy), IntPtr.Zero, IntPtr.Zero, dwFlags, new IntPtr(&userData))) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } // In some cases, the API would fail due to OOM but simply return a null pointer. if (userData.pbData == IntPtr.Zero) { throw new OutOfMemoryException(); } byte[] data = new byte[(int)userData.cbData]; Marshal.Copy(userData.pbData, data, 0, data.Length); return(data); } catch (EntryPointNotFoundException) { throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT")); } finally { if (pbDataIn.IsAllocated) { pbDataIn.Free(); } if (pOptionalEntropy.IsAllocated) { pOptionalEntropy.Free(); } if (userData.pbData != IntPtr.Zero) { CAPI.CAPISafe.ZeroMemory(userData.pbData, userData.cbData); CAPI.CAPISafe.LocalFree(userData.pbData); } } }
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 SubjectIdentifier(CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) { bool flag = true; byte *numPtr = (byte *)(void *)serialNumber.pbData; for (uint index = 0U; index < serialNumber.cbData; ++index) { if ((int)*numPtr++ != 0) { flag = false; break; } } if (flag) { byte[] numArray = new byte[(IntPtr)issuer.cbData]; Marshal.Copy(issuer.pbData, numArray, 0, numArray.Length); if (string.Compare("CN=Dummy Signer", new X500DistinguishedName(numArray).Name, StringComparison.OrdinalIgnoreCase) == 0) { this.Reset(SubjectIdentifierType.NoSignature, (object)null); return; } } if (flag) { this.m_type = SubjectIdentifierType.SubjectKeyIdentifier; this.m_value = (object)string.Empty; uint cbDecodedValue = 0U; SafeLocalAllocHandle decodedValue = SafeLocalAllocHandle.InvalidHandle; if (!CAPI.DecodeObject(new IntPtr(7L), issuer.pbData, issuer.cbData, out decodedValue, out cbDecodedValue)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } using (decodedValue) { CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(decodedValue.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO)); for (uint index1 = 0U; index1 < certNameInfo.cRDN; ++index1) { CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr((long)certNameInfo.rgRDN + (long)index1 * (long)Marshal.SizeOf(typeof(CAPI.CERT_RDN))), typeof(CAPI.CERT_RDN)); for (uint index2 = 0U; index2 < certRdn.cRDNAttr; ++index2) { CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)index2 * (long)Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR))), typeof(CAPI.CERT_RDN_ATTR)); if (string.Compare("1.3.6.1.4.1.311.10.7.1", certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0 && (int)certRdnAttr.dwValueType == 2) { byte[] numArray = new byte[(IntPtr)certRdnAttr.Value.cbData]; Marshal.Copy(certRdnAttr.Value.pbData, numArray, 0, numArray.Length); this.Reset(SubjectIdentifierType.SubjectKeyIdentifier, (object)X509Utils.EncodeHexString(numArray)); return; } } } } throw new CryptographicException(-2146889715); } else { CAPI.CERT_ISSUER_SERIAL_NUMBER pIssuerAndSerial; pIssuerAndSerial.Issuer = issuer; pIssuerAndSerial.SerialNumber = serialNumber; this.Reset(SubjectIdentifierType.IssuerAndSerialNumber, (object)PkcsUtils.DecodeIssuerSerial(pIssuerAndSerial)); } }
internal AsnEncodedData(Oid oid, CAPI.CRYPTOAPI_BLOB encodedBlob) : this(oid, CAPI.BlobToByteArray(encodedBlob)) { }
public static byte[] Protect(byte[] userData, byte[] optionalEntropy, DataProtectionScope scope) { if (userData == null) { throw new ArgumentNullException("userData"); } if (Environment.OSVersion.Platform == PlatformID.Win32Windows) { throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT")); } GCHandle pbDataIn = new GCHandle(); GCHandle pOptionalEntropy = new GCHandle(); CAPI.CRYPTOAPI_BLOB blob = new CAPI.CRYPTOAPI_BLOB(); RuntimeHelpers.PrepareConstrainedRegions(); try { pbDataIn = GCHandle.Alloc(userData, GCHandleType.Pinned); CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB(); dataIn.cbData = (uint)userData.Length; dataIn.pbData = pbDataIn.AddrOfPinnedObject(); CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB(); if (optionalEntropy != null) { pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned); entropy.cbData = (uint)optionalEntropy.Length; entropy.pbData = pOptionalEntropy.AddrOfPinnedObject(); } uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN; if (scope == DataProtectionScope.LocalMachine) { dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE; } unsafe { if (!CAPI.CryptProtectData(new IntPtr(&dataIn), String.Empty, new IntPtr(&entropy), IntPtr.Zero, IntPtr.Zero, dwFlags, new IntPtr(&blob))) { int lastWin32Error = Marshal.GetLastWin32Error(); // One of the most common reasons that DPAPI operations fail is that the user // profile is not loaded (for instance in the case of impersonation or running in a // service. In those cases, throw an exception that provides more specific details // about what happened. if (CAPI.ErrorMayBeCausedByUnloadedProfile(lastWin32Error)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_DpApi_ProfileMayNotBeLoaded")); } else { throw new CryptographicException(lastWin32Error); } } } // In some cases, the API would fail due to OOM but simply return a null pointer. if (blob.pbData == IntPtr.Zero) { throw new OutOfMemoryException(); } byte[] encryptedData = new byte[(int)blob.cbData]; Marshal.Copy(blob.pbData, encryptedData, 0, encryptedData.Length); return(encryptedData); } catch (EntryPointNotFoundException) { throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT")); } finally { if (pbDataIn.IsAllocated) { pbDataIn.Free(); } if (pOptionalEntropy.IsAllocated) { pOptionalEntropy.Free(); } if (blob.pbData != IntPtr.Zero) { CAPI.CAPISafe.ZeroMemory(blob.pbData, blob.cbData); CAPI.CAPISafe.LocalFree(blob.pbData); } } }
public X509Certificate2Collection Find(X509FindType findType, object findValue, bool validOnly) { DiagnosticUtility.DebugAssert(!this.certStoreHandle.IsInvalid, ""); uint dwFindType; SafeHGlobalHandle pvFindPara = SafeHGlobalHandle.InvalidHandle; SafeCertContextHandle pCertContext = SafeCertContextHandle.InvalidHandle; X509Certificate2Collection result = new X509Certificate2Collection(); SafeHGlobalHandle pvTemp = SafeHGlobalHandle.InvalidHandle; string strFindValue; byte[] bytes; try { switch (findType) { case X509FindType.FindBySubjectName: strFindValue = findValue as string; if (strFindValue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType()))); } dwFindType = CAPI.CERT_FIND_SUBJECT_STR; pvFindPara = SafeHGlobalHandle.AllocHGlobal(strFindValue); break; case X509FindType.FindByThumbprint: bytes = findValue as byte[]; if (bytes == null) { strFindValue = findValue as string; if (strFindValue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatchMulti, findType, typeof(string), typeof(byte[]), findValue.GetType()))); } bytes = SecurityUtils.DecodeHexString(strFindValue); } CAPI.CRYPTOAPI_BLOB blob = new CAPI.CRYPTOAPI_BLOB(); pvTemp = SafeHGlobalHandle.AllocHGlobal(bytes); blob.pbData = pvTemp.DangerousGetHandle(); blob.cbData = (uint)bytes.Length; dwFindType = CAPI.CERT_FIND_HASH; pvFindPara = SafeHGlobalHandle.AllocHGlobal(CAPI.CRYPTOAPI_BLOB.Size); Marshal.StructureToPtr(blob, pvFindPara.DangerousGetHandle(), false); break; case X509FindType.FindBySubjectDistinguishedName: if (!(findValue is string)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType()))); } dwFindType = CAPI.CERT_FIND_ANY; break; case X509FindType.FindByIssuerName: strFindValue = findValue as string; if (strFindValue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType()))); } dwFindType = CAPI.CERT_FIND_ISSUER_STR; pvFindPara = SafeHGlobalHandle.AllocHGlobal(strFindValue); break; case X509FindType.FindByIssuerDistinguishedName: if (!(findValue is string)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType()))); } dwFindType = CAPI.CERT_FIND_ANY; break; case X509FindType.FindBySerialNumber: bytes = findValue as byte[]; if (bytes == null) { strFindValue = findValue as string; if (strFindValue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatchMulti, findType, typeof(string), typeof(byte[]), findValue.GetType()))); } bytes = SecurityUtils.DecodeHexString(strFindValue); // reverse bits int len = bytes.Length; for (int i = 0, j = len - 1; i < bytes.Length / 2; ++i, --j) { byte tmp = bytes[i]; bytes[i] = bytes[j]; bytes[j] = tmp; } } findValue = bytes; dwFindType = CAPI.CERT_FIND_ANY; break; case X509FindType.FindBySubjectKeyIdentifier: bytes = findValue as byte[]; if (bytes == null) { strFindValue = findValue as string; if (strFindValue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatchMulti, findType, typeof(string), typeof(byte[]), findValue.GetType()))); } bytes = SecurityUtils.DecodeHexString(strFindValue); } findValue = bytes; dwFindType = CAPI.CERT_FIND_ANY; break; default: // Fallback to CLR implementation X509Store store = new X509Store(this.certStoreHandle.DangerousGetHandle()); try { return(store.Certificates.Find(findType, findValue, validOnly)); } finally { store.Close(); } } #pragma warning suppress 56523 // We are not interested in CRYPT_E_NOT_FOUND error, it return null anyway. pCertContext = CAPI.CertFindCertificateInStore(this.certStoreHandle, CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 0, dwFindType, pvFindPara, pCertContext); while (pCertContext != null && !pCertContext.IsInvalid) { X509Certificate2 cert; if (TryGetMatchingX509Certificate(pCertContext.DangerousGetHandle(), findType, dwFindType, findValue, validOnly, out cert)) { result.Add(cert); } // CER RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { // Suppress the finalizer #pragma warning suppress 56508 // CertFindCertificateInStore will release the prev one. GC.SuppressFinalize(pCertContext); #pragma warning suppress 56523 // We are not interested in CRYPT_E_NOT_FOUND error, it return null anyway. pCertContext = CAPI.CertFindCertificateInStore(this.certStoreHandle, CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 0, dwFindType, pvFindPara, pCertContext); } } } finally { if (pCertContext != null) { pCertContext.Close(); } pvFindPara.Close(); pvTemp.Close(); } return(result); }
/// <summary> /// Unprotect /// </summary> public static byte[] Unprotect(byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope) { if (encryptedData == null) throw new ArgumentNullException("encryptedData"); GCHandle pbDataIn = new GCHandle(); GCHandle pOptionalEntropy = new GCHandle(); CAPI.CRYPTOAPI_BLOB userData = new CAPI.CRYPTOAPI_BLOB(); try { pbDataIn = GCHandle.Alloc(encryptedData, GCHandleType.Pinned); CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB(); dataIn.cbData = (uint)encryptedData.Length; dataIn.pbData = pbDataIn.AddrOfPinnedObject(); CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB(); if (optionalEntropy != null) { pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned); entropy.cbData = (uint)optionalEntropy.Length; entropy.pbData = pOptionalEntropy.AddrOfPinnedObject(); } uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN; if (scope == DataProtectionScope.LocalMachine) dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE; unsafe { if (!CAPI.CryptUnprotectData(new IntPtr(&dataIn), IntPtr.Zero, new IntPtr(&entropy), IntPtr.Zero, IntPtr.Zero, dwFlags, new IntPtr(&userData))) throw new CryptographicException(Marshal.GetLastWin32Error()); } // In some cases, the API would fail due to OOM but simply return a null pointer. if (userData.pbData == IntPtr.Zero) throw new OutOfMemoryException(); byte[] data = new byte[(int)userData.cbData]; Marshal.Copy(userData.pbData, data, 0, data.Length); return data; } finally { if (pbDataIn.IsAllocated) pbDataIn.Free(); if (pOptionalEntropy.IsAllocated) pOptionalEntropy.Free(); if (userData.pbData != IntPtr.Zero) { CAPI.ZeroMemory(userData.pbData, userData.cbData); CAPI.LocalFree(userData.pbData); } } }
internal CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA(int size) { this.cbSize = (uint)size; this.dwSignerIndex = 0U; this.blob = new CAPI.CRYPTOAPI_BLOB(); }