Beispiel #1
0
        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();
                }
            }
        }
Beispiel #2
0
        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();
                }
            }
        }
Beispiel #3
0
        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();
                }
            }
        }
Beispiel #4
0
        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);
        }