private static byte[] DecodeOctetString(byte[] data) { const EncodingType type = EncodingType.X509_ASN_ENCODING; var handle = default(GCHandle); try { handle = GCHandle.Alloc(data, GCHandleType.Pinned); var size = 0u; const CryptDecodeFlags flags = CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG; if (!Crypto32.CryptDecodeObjectEx(type, X509_OCTET_STRING, handle.AddrOfPinnedObject(), (uint)data.Length, flags, IntPtr.Zero, out LocalBufferSafeHandle buffer, ref size)) { return(null); } using (buffer) { unsafe { var structure = (CRYPT_OBJID_BLOB)Marshal.PtrToStructure(buffer.DangerousGetHandle(), typeof(CRYPT_OBJID_BLOB)); var ret = new byte[structure.cbData]; Marshal.Copy(structure.pbData, ret, 0, ret.Length); return(ret); } } } finally { if (handle.IsAllocated) { handle.Free(); } } }
private static CtPublicKey DecodeSubjectPublicKeyInfo(byte[] publicKey) { const EncodingType encodingType = EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING; var handle = default(GCHandle); try { handle = GCHandle.Alloc(publicKey, GCHandleType.Pinned); LocalBufferSafeHandle buffer; var size = 0u; if (Crypto32.CryptDecodeObjectEx(encodingType, SUBJECT_PUBLIC_KEY_INFO, handle.AddrOfPinnedObject(), (uint)publicKey.Length, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out buffer, ref size)) { using (buffer) { //don't free the buffer until the structure's been fully read. var structure = (CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(buffer.DangerousGetHandle(), typeof(CERT_PUBLIC_KEY_INFO)); return(FromWin32Structure(structure)); } } else { return(null); } } finally { if (handle.IsAllocated) { handle.Free(); } } }
public IList <CertificatePolicy> GetPolicies(X509Certificate2 certificate) { var extension = certificate.Extensions[KnownOids.X509Extensions.CertificatePolicies]; if (extension == null) { return(new List <CertificatePolicy>()); } var handle = default(GCHandle); try { handle = GCHandle.Alloc(extension.RawData, GCHandleType.Pinned); LocalBufferSafeHandle buffer; var size = 0u; const EncodingType encodingType = EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING; if (!Crypto32.CryptDecodeObjectEx(encodingType, (IntPtr)16, handle.AddrOfPinnedObject(), (uint)extension.RawData.Length, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out buffer, ref size)) { //Can't decode it, gracefully retun an empty collection. return(new List <CertificatePolicy>()); } using (buffer) { var list = new List <CertificatePolicy>(); var policies = (CERT_POLICIES_INFO)Marshal.PtrToStructure(buffer.DangerousGetHandle(), typeof(CERT_POLICIES_INFO)); var certPolicySize = Marshal.SizeOf(typeof(CERT_POLICY_INFO)); for (var i = 0; i < policies.cPolicyInfo; i++) { var addr = new IntPtr(unchecked (((long)policies.rgPolicyInfo + (i * certPolicySize)))); var policy = (CERT_POLICY_INFO)Marshal.PtrToStructure(addr, typeof(CERT_POLICY_INFO)); var identifier = policy.pszPolicyIdentifier; list.Add(new CertificatePolicy { PolicyOid = new Oid(policy.pszPolicyIdentifier) }); } return(list); } } finally { if (handle.IsAllocated) { handle.Free(); } } }
public static unsafe byte[] BuildHashForPublicKeyBinary <THashAlgorithm>(X509Certificate2 certificate) where THashAlgorithm : HashAlgorithm, new() { var PUBLIC_KEY_INFO_TYPE = new IntPtr(8); const uint CRYPT_ENCODE_ALLOC_FLAG = 0x8000u; var handle = LocalBufferSafeHandle.Zero; try { var publicKey = certificate.GetPublicKey(); fixed(byte *publicKeyParametersPtr = certificate.PublicKey.EncodedParameters.RawData, publicKeyPtr = publicKey) { var publicKeyInfo = new CERT_PUBLIC_KEY_INFO(); publicKeyInfo.Algorithm = new CRYPT_ALGORITHM_IDENTIFIER(); publicKeyInfo.PublicKey = new CRYPT_BIT_BLOB(); publicKeyInfo.Algorithm.pszObjId = certificate.PublicKey.EncodedKeyValue.Oid.Value; publicKeyInfo.Algorithm.Parameters = new CRYPT_OBJID_BLOB(); publicKeyInfo.PublicKey.cbData = (uint)publicKey.Length; publicKeyInfo.PublicKey.cUnusedBits = 0; publicKeyInfo.PublicKey.pbData = publicKeyPtr; publicKeyInfo.Algorithm.Parameters.cbData = (uint)certificate.PublicKey.EncodedParameters.RawData.Length; publicKeyInfo.Algorithm.Parameters.pbData = publicKeyParametersPtr; uint size = 0; if (Crypto32.CryptEncodeObjectEx(EncodingType.X509_ASN_ENCODING, PUBLIC_KEY_INFO_TYPE, ref publicKeyInfo, CRYPT_ENCODE_ALLOC_FLAG, IntPtr.Zero, out handle, ref size)) { var encoded = new byte[size]; Marshal.Copy(handle.DangerousGetHandle(), encoded, 0, encoded.Length); using (var algorithm = new THashAlgorithm()) { return(algorithm.ComputeHash(encoded)); } } } } finally { handle.Dispose(); } return(null); }