Beispiel #1
0
        public static unsafe string CertGetNameString(
            SafeCertContextHandle certContext,
            Interop.Crypt32.CertNameType certNameType,
            Interop.Crypt32.CertNameFlags certNameFlags,
            Interop.Crypt32.CertNameStringType strType)
        {
            int cchCount = Crypt32.CertGetNameString(certContext, certNameType, certNameFlags, strType, null, 0);

            if (cchCount == 0)
            {
                throw Marshal.GetLastWin32Error().ToCryptographicException();
            }

            Span <char> buffer = cchCount <= 256 ? stackalloc char[cchCount] : new char[cchCount];

            fixed(char *ptr = &MemoryMarshal.GetReference(buffer))
            {
                if (Crypt32.CertGetNameString(certContext, certNameType, certNameFlags, strType, ptr, cchCount) == 0)
                {
                    throw Marshal.GetLastWin32Error().ToCryptographicException();
                }

                Debug.Assert(buffer[cchCount - 1] == '\0');
                return(new string(buffer.Slice(0, cchCount - 1)));
            }
        }
Beispiel #2
0
        internal static byte[] Decode(string input, Crypt32.CrypBinaryFlags flags,
                                      int inputSize)
        {
            int outputSize = 0;
            int pdwSkip;
            int pdwFlags;

            if (!Crypt32.CryptStringToBinary(input, inputSize, flags, IntPtr.Zero,
                                             ref outputSize, out pdwSkip, out pdwFlags))
            {
                int nativeError = Marshal.GetLastWin32Error();
                throw new InteropException(nativeError);
            }
            IntPtr nativeBuffer = IntPtr.Zero;

            try {
                nativeBuffer = Marshal.AllocCoTaskMem(outputSize);
                if (!Crypt32.CryptStringToBinary(input, inputSize, flags, nativeBuffer,
                                                 ref outputSize, out pdwSkip, out pdwFlags))
                {
                    int nativeError = Marshal.GetLastWin32Error();
                    throw new InteropException(nativeError);
                }
                byte[] result = new byte[outputSize];
                Marshal.Copy(nativeBuffer, result, 0, outputSize);
                return(result);
            }
            finally { if (IntPtr.Zero != nativeBuffer)
                      {
                          Marshal.FreeCoTaskMem(nativeBuffer);
                      }
            }
        }
Beispiel #3
0
        internal unsafe AuthenticodeTimestampCmsSignature(AsnEncodedData data, ICmsSignature owningSignature)
        {
            OwningSignature        = owningSignature;
            Kind                   = SignatureKind.AuthenticodeTimestamp;
            AdditionalCertificates = owningSignature.AdditionalCertificates;
            fixed(byte *dataPtr = data.RawData)
            {
                uint size = 0;

                if (Crypt32.CryptDecodeObjectEx(EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING, (IntPtr)500, new IntPtr(dataPtr), (uint)data.RawData.Length, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out var localBuffer, ref size))
                {
                    using (localBuffer)
                    {
                        var signerInfo = Marshal.PtrToStructure <CMSG_SIGNER_INFO>(localBuffer.DangerousGetHandle());
                        Signature               = ReadBlob(signerInfo.EncryptedHash);
                        DigestAlgorithm         = new Oid(signerInfo.HashAlgorithm.pszObjId);
                        HashEncryptionAlgorithm = new Oid(signerInfo.HashEncryptionAlgorithm.pszObjId);
                        SerialNumber            = ReadBlob(signerInfo.SerialNumber);
                        UnsignedAttributes      = ReadAttributes(signerInfo.UnauthAttrs);
                        SignedAttributes        = ReadAttributes(signerInfo.AuthAttrs);
                        var subjectId = new UniversalSubjectIdentifier(signerInfo.Issuer, signerInfo.SerialNumber);
                        if (subjectId.Type == SubjectIdentifierType.SubjectKeyIdentifier)
                        {
                            Certificate = FindCertificate((string)subjectId.Value, OwningSignature.AdditionalCertificates);
                        }
                        else if (subjectId.Type == SubjectIdentifierType.IssuerAndSerialNumber)
                        {
                            Certificate = FindCertificate((X509IssuerSerial)subjectId.Value, OwningSignature.AdditionalCertificates);
                        }
                    }
                }
Beispiel #4
0
        public void ShouldTimestampData()
        {
            var data       = new byte[] { 1, 2, 3 };
            var parameters = new CRYPT_TIMESTAMP_PARA
            {
                cExtension     = 0,
                fRequestCerts  = true,
                pszTSAPolicyId = null
            };

            var ok = Crypt32.CryptRetrieveTimeStamp("http://timestamp.digicert.com", CryptRetrieveTimeStampRetrievalFlags.NONE, 30 * 1000, "1.3.14.3.2.26", ref parameters, data, (uint)data.Length, out var pointer, IntPtr.Zero, IntPtr.Zero);

            Assert.True(ok);
            bool success = false;

            try
            {
                pointer.DangerousAddRef(ref success);
                Assert.True(success);
                var structure = Marshal.PtrToStructure <CRYPT_TIMESTAMP_CONTEXT>(pointer.DangerousGetHandle());
                var encoded   = new byte[structure.cbEncoded];
                Marshal.Copy(structure.pbEncoded, encoded, 0, encoded.Length);
            }
            finally
            {
                if (success)
                {
                    pointer.DangerousRelease();
                }
            }
        }
        public static List <TOCertificadoDigital> BuscarListaCertificados()
        {
            List <TOCertificadoDigital> lista = new List <TOCertificadoDigital>();

            IntPtr hCertStore = Crypt32.CertOpenSystemStore(IntPtr.Zero, "My");

            if (hCertStore == IntPtr.Zero)
            {
                throw new Exception("CertOpenSystemStore failed: " + Marshal.GetLastWin32Error().ToString());
            }

            IntPtr pCertContext = Crypt32.CertEnumCertificatesInStore(hCertStore, IntPtr.Zero);

            while (pCertContext != IntPtr.Zero)
            {
                //X509Certificate2 x509 = new X509Certificate2("c:", "dec2017",X509KeyStorageFlags.MachineKeySet);
                X509Certificate2 x509 = new X509Certificate2(pCertContext);
                //Verifica se o certificado foi emitido pelo ICP-Brasil
                if (x509.Issuer.Contains("O=ICP-Brasil") &&
                    x509.Issuer.Contains("C=BR"))
                {
                    if (ValidarCertificado(x509, DateTime.Now))
                    {
                        lista.Add(new TOCertificadoDigital(x509));
                    }
                }
                pCertContext = Crypt32.CertEnumCertificatesInStore(hCertStore, pCertContext);
            }

            return(lista);
        }
Beispiel #6
0
        public static DateTimeOffset?DecodeAuthenticodeTimestamp(AsnEncodedData data)
        {
            if (data.Oid.Value != KnownOids.SigningTime)
            {
                throw new ArgumentException("Data is not a signing time object.", nameof(data));
            }
            const EncodingType encodingType = EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING;

            unsafe
            {
                LocalBufferSafeHandle structBuffer;
                fixed(byte *buffer = data.RawData)
                {
                    uint size = 0;

                    if (!Crypt32.CryptDecodeObjectEx(encodingType, KnownOids.SigningTime, buffer, (uint)data.RawData.Length, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out structBuffer, ref size))
                    {
                        throw new InvalidOperationException("Failed to decode data.");
                    }
                }

                using (structBuffer)
                {
                    var  time        = Marshal.PtrToStructure <FILETIME>(structBuffer.DangerousGetHandle());
                    long fileTimeVal = (long)time.dwHighDateTime << 32 | (uint)time.dwLowDateTime;
                    return(DateTimeOffset.FromFileTime(fileTimeVal));
                }
            }
        }
Beispiel #7
0
        internal static IntPtr ImportRsaPublicKey(byte[] rawData)
        {
            CryptoProvider provider            = new CryptoProvider();
            IntPtr         nativeStructure     = IntPtr.Zero;
            int            nativeStructureSize = 0;

            try {
                if (!Advapi32.CryptDecodeObjectEx(CertificateEncodingType.X509Asn,
                                                  InteropHelpers.GetWellKnownOIDPointer(InteropHelpers.WellKnownOIDs.X509PublicKeyInfo),
                                                  rawData, rawData.Length, Advapi32.EncodingFlags.AllocateMemory, IntPtr.Zero,
                                                  ref nativeStructure, ref nativeStructureSize))
                {
                    throw new CryptographyException((WinErrors)(uint)Marshal.GetLastWin32Error());
                }
                IntPtr result = IntPtr.Zero;
                if (!Crypt32.CryptImportPublicKeyInfo(provider.Handle, CertificateEncodingType.X509Asn,
                                                      nativeStructure, out result))
                {
                    throw new CryptographyException((WinErrors)(uint)Marshal.GetLastWin32Error());
                }
                return(result);
            }
            finally {
                if (IntPtr.Zero != nativeStructure)
                {
                    if (IntPtr.Zero != Kernel32.LocalFree(nativeStructure))
                    {
                        throw new InteropException(Marshal.GetLastWin32Error());
                    }
                }
                provider.Dispose();
            }
        }
Beispiel #8
0
 private void DoUpdate(byte[] input, byte[] output, bool do_final)
 {
     Buffer.BlockCopy(input, 0, output, 0, (int)_key_size);
     int  crypted_size = (int)_key_size;
     bool result       = Crypt32.CryptEncrypt(_key, IntPtr.Zero, do_final,
                                              0, ref output, ref crypted_size, (int)_key_size);
 }
Beispiel #9
0
        static Wincrypt.CTL_ENTRY create_ctlentry(IntPtr handle, String thumbprint)
        {
            Wincrypt.CTL_ENTRY entry = new Wincrypt.CTL_ENTRY {
                SubjectIdentifier =
                {
                    pbData = get_thumbptr(thumbprint),
                    cbData = (UInt32)(thumbprint.Length / 2)
                }
            };

            List <UInt32> ids = new List <UInt32>();
            Boolean       end = false;

            do
            {
                UInt32 retn = Crypt32.CertEnumCertificateContextProperties(handle, 0);
                if (retn == 0)
                {
                    end = true;
                }
                else
                {
                    ids.Add(retn);
                }
            } while (!end);
            if (ids.Count > 0)
            {
                entry.cAttribute  = (UInt32)ids.Count;
                entry.rgAttribute = create_attributes(handle, ids);
            }
            return(entry);
        }
Beispiel #10
0
        void initializeLocal(String oid, OidGroupEnum group)
        {
            IntPtr ptr, oidptr;

            if (searchBy.ToLower() == "byvalue")
            {
                oidptr = Marshal.StringToHGlobalAnsi(oid);
                ptr    = Crypt32.CryptFindOIDInfo(Wincrypt.CRYPT_OID_INFO_OID_KEY, oidptr, (UInt32)group);
            }
            else
            {
                oidptr = Marshal.StringToHGlobalUni(oid);
                ptr    = Crypt32.CryptFindOIDInfo(Wincrypt.CRYPT_OID_INFO_NAME_KEY, oidptr, (UInt32)group);
            }
            if (ptr.Equals(IntPtr.Zero))
            {
                return;
            }
            if (_cng)
            {
                Wincrypt.CRYPT_OID_INFO OidInfo = (Wincrypt.CRYPT_OID_INFO)Marshal.PtrToStructure(ptr, typeof(Wincrypt.CRYPT_OID_INFO));
                FriendlyName = OidInfo.pwszName;
                Value        = OidInfo.pszOID;
                OidGroup     = (OidGroupEnum)OidInfo.dwGroupId;
            }
            else
            {
                Wincrypt.CRYPT_OID_INFO_Win2k3 OidInfo = (Wincrypt.CRYPT_OID_INFO_Win2k3)Marshal.PtrToStructure(ptr, typeof(Wincrypt.CRYPT_OID_INFO_Win2k3));
                FriendlyName = OidInfo.pwszName;
                Value        = OidInfo.pszOID;
                OidGroup     = (OidGroupEnum)OidInfo.dwGroupId;
            }
            Marshal.FreeHGlobal(oidptr);
        }
        public IReadOnlyList <ISignature> Extract(string filePath)
        {
            EncodingType          encodingType;
            CryptQueryContentType contentType;
            CryptQueryFormatType  formatType;
            CryptMsgSafeHandle    message = CryptMsgSafeHandle.InvalidHandle;
            var result = Crypt32.CryptQueryObject(CryptQueryObjectType.CERT_QUERY_OBJECT_FILE, filePath, CryptQueryContentFlagType.CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CryptQueryFormatFlagType.CERT_QUERY_FORMAT_FLAG_BINARY, CryptQueryObjectFlags.NONE, out encodingType, out contentType, out formatType, IntPtr.Zero, out message, IntPtr.Zero);

            if (!result)
            {
                var resultCode = Marshal.GetLastWin32Error();
                switch (unchecked ((uint)resultCode))
                {
                case 0x80092009:     //Cannot find request object. There's no signature.
                    return(Array.Empty <ISignature>());

                default:
                    throw new Win32Exception(resultCode, "Failed to extract signature.");
                }
            }
            using (message)
            {
                if (message.IsInvalid || message.IsClosed)
                {
                    return(Array.Empty <ISignature>());
                }
                return(GetSignatures(message));
            }
        }
        private bool ValidateNtAuthStore(X509Chain chain)
        {
            if (this.options.ValidationMethod != ClientCertificateValidationMethod.NtAuthStore)
            {
                return(true);
            }

            this.logger.LogTrace("Attempting to validate certificate against the NTAuth store");

            Crypt32.CERT_CHAIN_POLICY_STATUS status = new Crypt32.CERT_CHAIN_POLICY_STATUS();
            var para = new Crypt32.CERT_CHAIN_POLICY_PARA
            {
                cbSize = (uint)Marshal.SizeOf <Crypt32.CERT_CHAIN_POLICY_PARA>()
            };

            if (!Crypt32.CertVerifyCertificateChainPolicy(6, chain.ChainContext, para, ref status))
            {
                throw new CertificateValidationException("The function used to validate the certificate chain failed", new Win32Exception(Marshal.GetLastWin32Error()));
            }

            if (status.dwError != 0)
            {
                throw new CertificateValidationException("The certificate could not be validated against the NTAuth store. Ensure the issuer is from a trusted enterprise smart-card issuing CA", new Win32Exception((int)status.dwError));
            }

            this.logger.LogTrace("Certificate successfully validated against the NTAuth store");
            return(true);
        }
Beispiel #13
0
        void m_initialize(Oid oid, Int32 majorVersion, Int32 minorVersion)
        {
            Oid = _eoid;
            Asn1Utils.EncodeObjectIdentifier(oid);
            Wincrypt.CERT_TEMPLATE_EXT pvStructInfo = new Wincrypt.CERT_TEMPLATE_EXT {
                pszObjId       = oid.Value,
                dwMajorVersion = (UInt32)majorVersion,
                dwMinorVersion = (UInt32)minorVersion,
                fMinorVersion  = true
            };
            UInt32 pcbEncoded = 0;

            if (Crypt32.CryptEncodeObject(1, "1.3.6.1.4.1.311.21.7", ref pvStructInfo, null, ref pcbEncoded))
            {
                RawData = new Byte[pcbEncoded];
                Crypt32.CryptEncodeObject(1, "1.3.6.1.4.1.311.21.7", ref pvStructInfo, RawData, ref pcbEncoded);
                TemplateOid  = new Oid(pvStructInfo.pszObjId);
                MajorVersion = majorVersion;
                MinorVersion = minorVersion;
            }
            else
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
Beispiel #14
0
 void get_handle(Byte[] rawData)
 {
     Handle = Crypt32.CertCreateCTLContext(65537, rawData, (UInt32)rawData.Length);
     if (Handle.Equals(IntPtr.Zero))
     {
         throw new Exception("Unable to retieve context. The data is invalid.");
     }
 }
 /// <summary>
 /// Releases persistent handle and frees allocated resources.
 /// </summary>
 /// <exception cref="UninitializedObjectException">If <see cref="X509CRL2"/> object is not initialized.</exception>
 /// <returns><strong>True</strong> if the operation succeeds, otherwise <strong>False</strong>.</returns>
 protected override Boolean ReleaseHandle()
 {
     if (!handle.Equals(IntPtr.Zero))
     {
         return(Crypt32.CertFreeCRLContext(handle));
     }
     throw new UninitializedObjectException();
 }
Beispiel #16
0
 /// <summary>
 ///     Gets a <see cref="SafeCRLHandleContext" /> for the X509 certificate revocation list. The caller of this
 ///     method owns the returned safe handle, and should dispose of it when they no longer need it.
 ///     This handle can be used independently of the lifetime of the original X509 certificate revocation list.
 /// </summary>
 /// <returns>Handle to a <strong>CRL_CONTEXT</strong> structure.</returns>
 /// <permission cref="SecurityPermission">
 ///     The immediate caller must have SecurityPermission/UnmanagedCode to use this method
 /// </permission>
 /// <exception cref="UninitializedObjectException">An object is not initialized.</exception>
 public void GetSafeContext()
 {
     if (Handle.IsInvalid || Handle.IsClosed)
     {
         Handle = Handle = Crypt32.CertCreateCRLContext(65537, RawData, (UInt32)RawData.Length);
         GC.KeepAlive(this);
     }
 }
Beispiel #17
0
        public unsafe X509Certificate2 GenerateCertificateAuthority(PrivateKey privateKey, X500DistinguishedName dn, HashAlgorithm signatureAlgorithm, DateTime?notBefore = null, DateTime?notAfter = null)
        {
            {
                fixed(byte *dnPtr = dn.RawData)
                {
                    var blob = new NATIVE_CRYPTOAPI_BLOB
                    {
                        cbData = (uint)dn.RawData.Length,
                        pbData = dnPtr
                    };
                    var signatureAlgorithmIdentifier = new CRYPT_ALGORITHM_IDENTIFIER
                    {
                        pszObjId = HashAlgorithmToSignatureAlgorithm(privateKey, signatureAlgorithm)
                    };

                    using (var extensions = new MarshalX509ExtensionCollection())
                    {
                        using (extensions.Freeze())
                        {
                            extensions.Add(new X509BasicConstraintsExtension(true, true, 1, true));
                            extensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.CrlSign | X509KeyUsageFlags.KeyCertSign, true));
                            extensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection {
                                new Oid(OIDs.EKU_SERVER)
                            }, false));
                            using (var publicKey = privateKey.ToPublicKey())
                            {
                                using (var sha1 = new SHA1CryptoServiceProvider())
                                {
                                    var pubKeyHash = sha1.ComputeHash(publicKey.Key);
                                    extensions.Add(new X509SubjectKeyIdentifierExtension(pubKeyHash, false));
                                    extensions.Add(new X509AuthorityKeyIdentifierExtension(pubKeyHash, null));
                                }
                            }
                        }
                        var certExtensions = extensions.Extensions;
                        var keyProvInfo    = new CRYPT_KEY_PROV_INFO
                        {
                            cProvParam        = 0,
                            dwKeySpec         = privateKey.KeySpec,
                            dwProvType        = privateKey.Handle.IsNCryptKey ? ProviderType.CNG : ProviderType.PROV_RSA_AES,
                            pwszProvName      = privateKey.ProviderName,
                            dwFlags           = 0,
                            pwszContainerName = privateKey.Name
                        };
                        var beginning   = new SYSTEMTIME(notBefore ?? DateTime.UtcNow.AddHours(-1));
                        var expiration  = new SYSTEMTIME(notAfter ?? DateTime.UtcNow.AddHours(-1).AddYears(30));
                        var certContext = Crypt32.CertCreateSelfSignCertificate(privateKey.Handle, ref blob, SelfSignFlags.NONE, ref keyProvInfo, ref signatureAlgorithmIdentifier, beginning, expiration, ref certExtensions);
                        if (certContext == IntPtr.Zero)
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                        return(new X509Certificate2(certContext));
                    }
                }
            }
        }
Beispiel #18
0
 /// <summary>
 ///     Gets a <see cref="SafeCTLHandleContext" /> for the X509 certificate revocation list. The caller of this
 ///     method owns the returned safe handle, and should dispose of it when they no longer need it.
 ///     This handle can be used independently of the lifetime of the original X509 certificate revocation list.
 /// </summary>
 /// <returns>Safe handle to a current CTL instance.</returns>
 /// <permission cref="SecurityPermission">
 ///     The immediate caller must have SecurityPermission/UnmanagedCode to use this method
 /// </permission>
 public SafeCTLHandleContext GetSafeContext()
 {
     if (!Handle.Equals(IntPtr.Zero))
     {
         SafeCTLHandleContext safeContext = Crypt32.CertDuplicateCTLContext(Handle);
         GC.KeepAlive(this);
         return(safeContext);
     }
     throw new UninitializedObjectException();
 }
Beispiel #19
0
 /// <summary>
 ///     Gets a <see cref="SafeCTLHandleContext" /> for the X509 certificate revocation list. The caller of this
 ///     method owns the returned safe handle, and should dispose of it when they no longer need it.
 ///     This handle can be used independently of the lifetime of the original X509 certificate revocation list.
 /// </summary>
 /// <returns>Safe handle to a current CTL instance.</returns>
 /// <permission cref="SecurityPermission">
 ///     The immediate caller must have SecurityPermission/UnmanagedCode to use this method
 /// </permission>
 public SafeCTLHandleContext GetSafeContext()
 {
     if (ctx == null || ctx.IsInvalid || ctx.IsClosed)
     {
         ctx = Crypt32.CertCreateCTLContext(65537, RawData, (UInt32)RawData.Length);
         GC.KeepAlive(this);
         return(ctx);
     }
     return(ctx);
 }
Beispiel #20
0
        public UniversalSubjectIdentifier(CRYPTOAPI_BLOB issuer, CRYPTOAPI_BLOB serialNumber)
        {
            var allZeroSerial = IsBlobAllZero(serialNumber);

            if (allZeroSerial)
            {
                var  x500Name = LocalBufferSafeHandle.Zero;
                var  flags    = EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING;
                uint size     = 0;
                if (Crypt32.CryptDecodeObjectEx(flags, (IntPtr)7, issuer.pbData, issuer.cbData, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out x500Name, ref size))
                {
                    using (x500Name)
                    {
                        var info = Marshal.PtrToStructure <CERT_NAME_INFO>(x500Name.DangerousGetHandle());
                        for (var i = 0L; i < info.cRDN; i++)
                        {
                            var rdn = Marshal.PtrToStructure <CERT_RDN>(new IntPtr(info.rgRDN.ToInt64() + i * Marshal.SizeOf <CERT_RDN>()));
                            for (var j = 0; j < rdn.cRDNAttr; j++)
                            {
                                var attribute = Marshal.PtrToStructure <CERT_RDN_ATTR>(new IntPtr(rdn.rgRDNAttr.ToInt64() + j * Marshal.SizeOf <CERT_RDN_ATTR>()));
                                if (attribute.pszObjId == KnownOids.KeyId)
                                {
                                    Type = SubjectIdentifierType.SubjectKeyIdentifier;
                                    var ski = new byte[attribute.Value.cbData];
                                    Marshal.Copy(attribute.Value.pbData, ski, 0, ski.Length);
                                    Value = HashHelpers.HexEncodeBigEndian(ski);
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            unsafe
            {
                var result = Crypt32.CertNameToStr(EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING, new IntPtr(&issuer), CertNameStrType.CERT_X500_NAME_STR | CertNameStrType.CERT_NAME_STR_REVERSE_FLAG, null, 0);
                if (result <= 1)
                {
                    throw new InvalidOperationException();
                }
                var builder = new StringBuilder((int)result);
                var final   = Crypt32.CertNameToStr(EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING, new IntPtr(&issuer), CertNameStrType.CERT_X500_NAME_STR | CertNameStrType.CERT_NAME_STR_REVERSE_FLAG, builder, result);
                if (final <= 1)
                {
                    throw new InvalidOperationException();
                }
                var serial = new byte[serialNumber.cbData];
                Marshal.Copy(serialNumber.pbData, serial, 0, serial.Length);
                var issuerSerial = new X509IssuerSerial();
                issuerSerial.IssuerName   = builder.ToString();
                issuerSerial.SerialNumber = HashHelpers.HexEncodeBigEndian(serial);
                Value = issuerSerial;
                Type  = SubjectIdentifierType.IssuerAndSerialNumber;
            }
        }
        private Task <TimestampResult> Win32TimeStamp(Uri timestampServer, HashAlgorithmName timestampAlgorithm, TimestampNonceFactory nonce)
        {
            var oid        = HashAlgorithmTranslator.TranslateFromNameToOid(timestampAlgorithm);
            var parameters = new CRYPT_TIMESTAMP_PARA
            {
                cExtension    = 0,
                fRequestCerts = true
            };

            parameters.Nonce.cbData   = nonce.Size;
            parameters.Nonce.pbData   = nonce.NoncePointer;
            parameters.pszTSAPolicyId = null;
            var(signatureDocument, timestampSubject) = GetSignatureToTimestamp(_part);
            var winResult = Crypt32.CryptRetrieveTimeStamp(
                timestampServer.AbsoluteUri,
                CryptRetrieveTimeStampRetrievalFlags.NONE,
                (uint)Timeout.TotalMilliseconds,
                oid.Value,
                ref parameters,
                timestampSubject,
                (uint)timestampSubject.Length,
                out var context,
                IntPtr.Zero,
                IntPtr.Zero
                );

            if (!winResult)
            {
                return(Task.FromResult(TimestampResult.Failed));
            }
            using (context)
            {
                var refSuccess = false;
                try
                {
                    context.DangerousAddRef(ref refSuccess);
                    if (!refSuccess)
                    {
                        return(Task.FromResult(TimestampResult.Failed));
                    }
                    var structure = Marshal.PtrToStructure <CRYPT_TIMESTAMP_CONTEXT>(context.DangerousGetHandle());
                    var encoded   = new byte[structure.cbEncoded];
                    Marshal.Copy(structure.pbEncoded, encoded, 0, encoded.Length);
                    ApplyTimestamp(signatureDocument, _part, encoded);
                    return(Task.FromResult(TimestampResult.Success));
                }
                finally
                {
                    if (refSuccess)
                    {
                        context.DangerousRelease();
                    }
                }
            }
        }
Beispiel #22
0
        internal void import_key(byte[] key_blob)
        {
            bool result = Crypt32.CryptImportKey(_provider.Handle, key_blob,
                                                 key_blob.Length, IntPtr.Zero, 0, out _key);
            int param_size = sizeof(uint);

            byte[] rawData = new byte[sizeof(int)];
            Crypt32.CryptGetKeyParam(_key, Crypt32.KP_KEYLEN, ref rawData, ref param_size, 0);
            _key_size  = (((((rawData[3] * 256) + rawData[2]) * 256) + rawData[1]) + 256) + rawData[0];
            _key_size /= 8;
        }
Beispiel #23
0
        private static unsafe Task <(TimestampResult, byte[])> SubmitTimestampRequest(Uri timestampUri, Oid digestOid, TimestampNonce nonce, TimeSpan timeout, byte[] digest)
        {
            var parameters = new CRYPT_TIMESTAMP_PARA
            {
                cExtension    = 0,
                fRequestCerts = true
            };

            using (var cNonce = nonce.Nonce.Pin())
            {
                parameters.Nonce.cbData   = (uint)nonce.Nonce.Length;
                parameters.Nonce.pbData   = new IntPtr(cNonce.Pointer);
                parameters.pszTSAPolicyId = null;
                var winResult = Crypt32.CryptRetrieveTimeStamp(
                    timestampUri.AbsoluteUri,
                    CryptRetrieveTimeStampRetrievalFlags.TIMESTAMP_DONT_HASH_DATA,
                    (uint)timeout.TotalMilliseconds,
                    digestOid.Value,
                    ref parameters,
                    digest,
                    (uint)digest.Length,
                    out var context,
                    IntPtr.Zero,
                    IntPtr.Zero
                    );
                if (!winResult)
                {
                    return(Task.FromResult <(TimestampResult, byte[])>((TimestampResult.Failed, null)));
                }
                using (context)
                {
                    var refSuccess = false;
                    try
                    {
                        context.DangerousAddRef(ref refSuccess);
                        if (!refSuccess)
                        {
                            return(Task.FromResult <(TimestampResult, byte[])>((TimestampResult.Failed, null)));
                        }
                        var structure = Marshal.PtrToStructure <CRYPT_TIMESTAMP_CONTEXT>(context.DangerousGetHandle());
                        var encoded   = new byte[structure.cbEncoded];
                        Marshal.Copy(structure.pbEncoded, encoded, 0, encoded.Length);
                        return(Task.FromResult <(TimestampResult, byte[])>((TimestampResult.Success, encoded)));
                    }
                    finally
                    {
                        if (refSuccess)
                        {
                            context.DangerousRelease();
                        }
                    }
                }
            }
        }
Beispiel #24
0
        public static Byte[] CryptStringToBinary(String inputString, CryptEncoding inputEncoding = CryptEncoding.CRYPT_STRING_ANY)
        {
            UInt32 pcbBinary = 0;

            if (Crypt32.CryptStringToBinary(inputString, (UInt32)inputString.Length, (UInt32)inputEncoding, null, ref pcbBinary, 0, 0))
            {
                Byte[] pbBinary = new Byte[pcbBinary];
                Crypt32.CryptStringToBinary(inputString, (UInt32)inputString.Length, (UInt32)inputEncoding, pbBinary, ref pcbBinary, 0, 0);
                return(pbBinary);
            }
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
Beispiel #25
0
 static void unregisterCNG(IEnumerable <Oid2> oid)
 {
     if (oid.Select(oid2 => new Wincrypt.CRYPT_OID_INFO {
         cbSize = Marshal.SizeOf(typeof(Wincrypt.CRYPT_OID_INFO)),
         pszOID = oid2.Value,
         pwszName = oid2.FriendlyName,
         dwGroupId = (Int32)oid2.OidGroup
     }).Any(oidinfo => !Crypt32.CryptUnregisterOIDInfo(oidinfo)))
     {
         throw new Win32Exception(Marshal.GetLastWin32Error());
     }
 }
Beispiel #26
0
        internal void init(Mode aes_mode, KeySize aes_key_size, byte[] key)
        {
            _mode = aes_mode;
            switch (aes_key_size)
            {
            case KeySize.Aes128:
                _key_size = 16;
                break;

            case KeySize.Aes192:
                _key_size = 24;
                break;

            case KeySize.Aes256:
                _key_size = 32;
                break;

            default:
                _key_size = 0;
                break;
            }
            _counter.Zeroize();
            _counter_out.Zeroize();
            _keystream_pointer = 0xFFFF;
            // initialize WinCrypt AES-128 key.
            ms_aes_key key_blob = new ms_aes_key();

            key_blob.header.bType    = BlobType.PlainText;
            key_blob.header.bVersion = CurrentBlobVersion;
            key_blob.header.reserved = 0;
            key_blob.header.aiKeyAlg = (uint)aes_key_size;
            key_blob.size            = _key_size;
            Buffer.BlockCopy(key, 0, key_blob.key, 0, (int)key_blob.size);
            int    nativeKeySize;
            IntPtr nativeKey = key_blob.Serialize(out nativeKeySize);

            try {
                bool result = Crypt32.CryptImportKey(_provider.Handle, nativeKey,
                                                     nativeKeySize, IntPtr.Zero, 0, out _key);
            }
            finally { Marshal.FreeCoTaskMem(nativeKey); }
            _mode = aes_mode;
            // WinCrypt cannot do CTR mode, we have to do it manually.
            IntPtr buffer = Marshal.AllocCoTaskMem(sizeof(int));

            try {
                int mode = (int)((aes_mode == Mode.Ctr) ? Mode.Ecb : aes_mode);
                Marshal.WriteInt32(buffer, mode);
                bool result = Crypt32.CryptSetKeyParam(_key, 4 /* KP_MODE*/, buffer, 0);
            }
            finally { Marshal.FreeCoTaskMem(buffer); }
        }
Beispiel #27
0
        private static unsafe IReadOnlyList <ICmsSignature> GetSignatures(CryptMsgSafeHandle messageHandle)
        {
            var countSize = 0u;

            if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_COUNT_PARAM, 0, LocalBufferSafeHandle.Zero, ref countSize))
            {
                return(Array.Empty <ICmsSignature>());
            }
            uint signerCount;

            using (var countHandle = LocalBufferSafeHandle.Alloc(countSize))
            {
                if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_COUNT_PARAM, 0, countHandle, ref countSize))
                {
                    return(Array.Empty <ICmsSignature>());
                }
                signerCount = (uint)Marshal.ReadInt32(countHandle.DangerousGetHandle());
            }
            var signatures  = new List <ICmsSignature>();
            var contentSize = 0u;

            byte[] content = null;
            if (Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_CONTENT_PARAM, 0, LocalBufferSafeHandle.Zero, ref contentSize))
            {
                using (var contentHandle = LocalBufferSafeHandle.Alloc(contentSize))
                {
                    if (Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_CONTENT_PARAM, 0, contentHandle, ref contentSize))
                    {
                        content = new byte[contentSize];
                        Marshal.Copy(contentHandle.DangerousGetHandle(), content, 0, (int)contentSize);
                    }
                }
            }
            for (var i = 0u; i < signerCount; i++)
            {
                var signerSize = 0u;
                if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, i, LocalBufferSafeHandle.Zero, ref signerSize))
                {
                    continue;
                }
                using (var signerHandle = LocalBufferSafeHandle.Alloc(signerSize))
                {
                    if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, i, signerHandle, ref signerSize))
                    {
                        continue;
                    }
                    var signature = new CmsSignature(SignatureKind.Signature, messageHandle, signerHandle, content);
                    signatures.Add(signature);
                }
            }
            return(signatures.AsReadOnly());
        }
Beispiel #28
0
        private void SetKey(byte[] keyData, string keyType)
        {
            int key_blob_size = 0;

            _key_blob = null;
            bool result = Crypt32.CryptDecodeObject(Crypt32.X509_ASN_ENCODING, keyType,
                                                    keyData, keyData.Length, 0, ref _key_blob, ref key_blob_size);

            _key_blob = new byte[key_blob_size];
            result    = Crypt32.CryptDecodeObject(Crypt32.X509_ASN_ENCODING, keyType,
                                                  keyData, keyData.Length, 0, ref _key_blob, ref key_blob_size);
            import_key(_key_blob);
        }
Beispiel #29
0
 static void registerCNG(Oid oid, OidGroupEnum group)
 {
     Wincrypt.CRYPT_OID_INFO oidinfo = new Wincrypt.CRYPT_OID_INFO {
         cbSize    = Marshal.SizeOf(typeof(Wincrypt.CRYPT_OID_INFO)),
         pszOID    = oid.Value,
         pwszName  = oid.FriendlyName,
         dwGroupId = (Int32)@group
     };
     if (!Crypt32.CryptRegisterOIDInfo(oidinfo, 0))
     {
         throw new Win32Exception(Marshal.GetLastWin32Error());
     }
 }
Beispiel #30
0
        /// <summary>
        /// Computes the hash value of the specified byte array using the specified hash algorithm, and signs the resulting hash value.
        /// </summary>
        /// <param name="certificate">An <see cref="X509Certificate2"/> object of the signer certificate.</param>
        /// <param name="message">Message to be signed.</param>
        /// <param name="hashAlgorithm">The name of the hash algorithm to use in the signature.</param>
        /// <returns>The signature for the specified data.</returns>
        public static Byte[] SignMessage(X509Certificate2 certificate, Byte[] message, Oid hashAlgorithm)
        {
            IntPtr  phCryptProv      = IntPtr.Zero;
            UInt32  pdwKeySpec       = 0;
            Boolean pfCallerFreeProv = false;

            if (!Crypt32.CryptAcquireCertificatePrivateKey(certificate.Handle, 0x00010000, IntPtr.Zero, ref phCryptProv, ref pdwKeySpec, ref pfCallerFreeProv))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            Oid2 hashalgorithm = new Oid2(
                hashAlgorithm.FriendlyName.ToLower()
                .Replace("rsa", null)
                .Replace("ecdsa", null),
                OidGroupEnum.HashAlgorithm, true);
            String hashAlg;

            // true -> CNG, false -> legacy
            if (pdwKeySpec == UInt32.MaxValue)
            {
                Byte[] hashBytes = calculateHash(message, hashalgorithm, false, out hashAlg);
                try {
                    UInt32 pcbResult;
                    Int32  hresult = nCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, (UInt32)hashBytes.Length, null, 0, out pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    Byte[] pbSignature = new byte[pcbResult];
                    hresult = nCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, (UInt32)hashBytes.Length, pbSignature, (UInt32)pbSignature.Length, out pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    return(pbSignature);
                } finally {
                    if (pfCallerFreeProv)
                    {
                        nCrypt.NCryptFreeObject(phCryptProv);
                    }
                }
            }
            if (pfCallerFreeProv)
            {
                AdvAPI.CryptReleaseContext(phCryptProv, 0);
            }
            calculateHash(message, hashalgorithm, false, out hashAlg);
            RSACryptoServiceProvider key = (RSACryptoServiceProvider)certificate.PrivateKey;

            return(key.SignData(message, hashAlg));
        }