private static unsafe SafeLocalAllocHandle EncodePublicKey(PublicKey key) { SafeLocalAllocHandle invalidHandle = SafeLocalAllocHandle.InvalidHandle; CAPIBase.CERT_PUBLIC_KEY_INFO2 *handle = null; string s = key.Oid.Value; byte[] rawData = key.EncodedParameters.RawData; byte[] source = key.EncodedKeyValue.RawData; uint num = (uint)(((Marshal.SizeOf(typeof(CAPIBase.CERT_PUBLIC_KEY_INFO2)) + System.Security.Cryptography.X509Certificates.X509Utils.AlignedLength((uint)(s.Length + 1))) + System.Security.Cryptography.X509Certificates.X509Utils.AlignedLength((uint)rawData.Length)) + source.Length); invalidHandle = CAPI.LocalAlloc(0x40, new IntPtr((long)num)); handle = (CAPIBase.CERT_PUBLIC_KEY_INFO2 *)invalidHandle.DangerousGetHandle(); IntPtr destination = new IntPtr(((long)((ulong)handle)) + Marshal.SizeOf(typeof(CAPIBase.CERT_PUBLIC_KEY_INFO2))); IntPtr ptr2 = new IntPtr(((long)destination) + System.Security.Cryptography.X509Certificates.X509Utils.AlignedLength((uint)(s.Length + 1))); IntPtr ptr3 = new IntPtr(((long)ptr2) + System.Security.Cryptography.X509Certificates.X509Utils.AlignedLength((uint)rawData.Length)); handle->Algorithm.pszObjId = destination; byte[] bytes = new byte[s.Length + 1]; Encoding.ASCII.GetBytes(s, 0, s.Length, bytes, 0); Marshal.Copy(bytes, 0, destination, bytes.Length); if (rawData.Length > 0) { handle->Algorithm.Parameters.cbData = (uint)rawData.Length; handle->Algorithm.Parameters.pbData = ptr2; Marshal.Copy(rawData, 0, ptr2, rawData.Length); } handle->PublicKey.cbData = (uint)source.Length; handle->PublicKey.pbData = ptr3; Marshal.Copy(source, 0, ptr3, source.Length); return(invalidHandle); }
private static unsafe byte[] EncodePublicKey(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm) { if (key == null) { throw new ArgumentNullException("key"); } SafeLocalAllocHandle handle = EncodePublicKey(key); CAPIBase.CERT_PUBLIC_KEY_INFO2 *cert_public_key_infoPtr = (CAPIBase.CERT_PUBLIC_KEY_INFO2 *)handle.DangerousGetHandle(); byte[] sourceArray = new byte[20]; byte[] destinationArray = null; fixed(byte *numRef = sourceArray) { uint length = (uint)sourceArray.Length; IntPtr pbComputedHash = new IntPtr((void *)numRef); try { if ((algorithm == X509SubjectKeyIdentifierHashAlgorithm.Sha1) || (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm)) { if (!CAPISafe.CryptHashCertificate(IntPtr.Zero, 0x8004, 0, cert_public_key_infoPtr->PublicKey.pbData, cert_public_key_infoPtr->PublicKey.cbData, pbComputedHash, new IntPtr((void *)&length))) { throw new CryptographicException(Marshal.GetHRForLastWin32Error()); } } else { if (X509SubjectKeyIdentifierHashAlgorithm.CapiSha1 != algorithm) { throw new ArgumentException("algorithm"); } if (!CAPISafe.CryptHashPublicKeyInfo(IntPtr.Zero, 0x8004, 0, 1, new IntPtr((void *)cert_public_key_infoPtr), pbComputedHash, new IntPtr((void *)&length))) { throw new CryptographicException(Marshal.GetHRForLastWin32Error()); } } if (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm) { destinationArray = new byte[8]; Array.Copy(sourceArray, sourceArray.Length - 8, destinationArray, 0, destinationArray.Length); destinationArray[0] = (byte)(destinationArray[0] & 15); destinationArray[0] = (byte)(destinationArray[0] | 0x40); } else { destinationArray = sourceArray; if (sourceArray.Length > length) { destinationArray = new byte[length]; Array.Copy(sourceArray, 0, destinationArray, 0, destinationArray.Length); } } } finally { handle.Dispose(); } } return(EncodeExtension(destinationArray)); }