private void ChangeContextButton(CertContext flip) { Context = flip; switch (flip) { case CertContext.User: if (!Credential_Manager_App.MainWindow.IsAdministrator()) { uacShield.IsEnabled = true; uacShield.Visibility = Visibility.Visible; } switchContextBtn.Content = userToMachCtx; certCol = Encryption.GetInstalledCerts(StoreLocation.CurrentUser); usingStore = StoreLocation.CurrentUser; break; case CertContext.Machine: uacShield.Visibility = Visibility.Hidden; uacShield.IsEnabled = false; switchContextBtn.Content = machToUserCtx; certCol = Encryption.GetInstalledCerts(StoreLocation.LocalMachine); usingStore = StoreLocation.LocalMachine; break; } listOCerts.ItemsSource = certCol; }
public static Signer GetSignerFromStateData(IntPtr StateData) { // Sanity check if (StateData == IntPtr.Zero) { return(null); } // 1. Get provider data from state data IntPtr pProvData = WTHelperProvDataFromStateData(StateData); if (pProvData == IntPtr.Zero) { return(null); } CryptProviderData provData = (CryptProviderData)Marshal.PtrToStructure(pProvData, typeof(CryptProviderData)); // 2. Get provider signer from provider data IntPtr pSgnr = WTHelperGetProvSignerFromChain(pProvData, 0, false, 0); if (pSgnr == IntPtr.Zero) { return(null); } CryptProviderSgnr sgnr = (CryptProviderSgnr)Marshal.PtrToStructure(pSgnr, typeof(CryptProviderSgnr)); if (sgnr.pasCertChain == null) { return(null); } if (sgnr.csCertChain == 0) { return(null); } // 3. Get provider cert from provider signer var providerCerts = new List <CryptProviderCert>(); var ptr = sgnr.pasCertChain; int sizeof_cryptProviderCert = Marshal.SizeOf(new CryptProviderCert()); // Collect certificate chain into a list for (int i = 0; i < sgnr.csCertChain; i++) { providerCerts.Add((CryptProviderCert)Marshal.PtrToStructure(ptr, typeof(CryptProviderCert))); ptr = (IntPtr)((int)ptr + sizeof_cryptProviderCert); // Sanity check const int MAX_CERT_CHAIN_LENGTH = 20; // Arbitrary max length of a chain I'm willing to use if (i > MAX_CERT_CHAIN_LENGTH) { break; } } // This is actually a list, but I only care about the first element CryptProviderCert cert = providerCerts[0]; // 4. Get cert context CertContext certContext = (CertContext)Marshal.PtrToStructure(cert.pCert, typeof(CertContext)); // 5. Get cert info CertInfo certInfo = (CertInfo)Marshal.PtrToStructure(certContext.pCertInfo, typeof(CertInfo)); if (certInfo == null) { return(null); } CRYPTOAPI_BLOB subject = certInfo.Subject; // 6. Get subject X.500 string string issuer = GetCertIssuerString(subject); // Get the best name for identifying this cert X500DistinguishedName x500DN = new X500DistinguishedName(issuer); string signerName = getBestName(x500DN); // Clean up the signer name signerName = signerName.Replace("\"", ""); signerName = signerName.Trim(); // Remove trailing "\x0d" int serialNumberLen = certInfo.SerialNumber.cbData; if (serialNumberLen < 0 || serialNumberLen > 256) { // TODO Should throw an error } var serialNumber = new byte[serialNumberLen]; Marshal.Copy(certInfo.SerialNumber.pbData, serialNumber, 0, serialNumberLen); // Byte order seems to be reversed, so I'm flipping it here Array.Reverse(serialNumber, 0, serialNumberLen); var certEntity = new Certificate { Version = certInfo.dwVersion, Issuer = issuer, SerialNumber = serialNumber, DigestAlgorithm = certInfo.SignatureAlgorithm.pszObjId, DigestEncryptionAlgorithm = certInfo.SubjectPublicKeyInfoAlgo.Algorithm.pszObjId }; var signer = new Signer { Name = signerName, Timestamp = DateTime.FromFileTime((long)sgnr.sftVerifyAsOf), SigningCert = certEntity }; return(signer); }
private static string GetSignerNameFromStateData(IntPtr stateData) { // Well, here's a shitload of indirection for you... // 1. State data -> Provider data IntPtr provData = Win32.WTHelperProvDataFromStateData(stateData); if (provData == IntPtr.Zero) { return(null); } // 2. Provider data -> Provider signer IntPtr signerInfo = Win32.WTHelperGetProvSignerFromChain(provData, 0, false, 0); if (signerInfo == IntPtr.Zero) { return(null); } CryptProviderSgnr sngr = (CryptProviderSgnr)Marshal.PtrToStructure(signerInfo, typeof(CryptProviderSgnr)); if (sngr.CertChain == IntPtr.Zero) { return(null); } if (sngr.CertChainCount == 0) { return(null); } // 3. Provider signer -> Provider cert CryptProviderCert cert = (CryptProviderCert)Marshal.PtrToStructure(sngr.CertChain, typeof(CryptProviderCert)); if (cert.Cert == IntPtr.Zero) { return(null); } // 4. Provider cert -> Cert context CertContext context = (CertContext)Marshal.PtrToStructure(cert.Cert, typeof(CertContext)); if (context.CertInfo != IntPtr.Zero) { // 5. Cert context -> Cert info CertInfo certInfo = (CertInfo)Marshal.PtrToStructure(context.CertInfo, typeof(CertInfo)); unsafe { using (MemoryAlloc buffer = new MemoryAlloc(0x200)) { int length; // 6. Cert info subject -> Subject X.500 string length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); if (length > buffer.Size / 2) { buffer.ResizeNew(length * 2); length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); } string name = buffer.ReadUnicodeString(0); // 7. Subject X.500 string -> CN or OU value string value = GetX500Value(name, "CN"); if (string.IsNullOrEmpty(value)) { value = GetX500Value(name, "OU"); } return(value); } } } return(null); }