private static string GetKeyName(object key) { ICspAsymmetricAlgorithm algorithm = key as ICspAsymmetricAlgorithm; X509Certificate certificate = key as X509Certificate; X509Certificate2 certificate2 = key as X509Certificate2; string str = null; if ((algorithm != null) && (algorithm.CspKeyContainerInfo.KeyContainerName != null)) { str = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", new object[] { algorithm.CspKeyContainerInfo.KeyContainerName }); } else if (certificate2 != null) { str = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", new object[] { certificate2.GetNameInfo(X509NameType.SimpleName, false) }); } else if (certificate != null) { str = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", new object[] { certificate.Subject }); } else { str = key.GetHashCode().ToString("x8", CultureInfo.InvariantCulture); } return(string.Format(CultureInfo.InvariantCulture, "{0}#{1}", new object[] { key.GetType().Name, str })); }
private static IntPtr GetProviderInfo(X509Certificate2 cert) { if (cert == null || !cert.HasPrivateKey) { return(IntPtr.Zero); } ICspAsymmetricAlgorithm key = (ICspAsymmetricAlgorithm)cert.PrivateKey; const int PVK_TYPE_KEYCONTAINER = 2; if (key == null) { return(IntPtr.Zero); } SIGNER_PROVIDER_INFO providerInfo = new SIGNER_PROVIDER_INFO { cbSize = (uint)Marshal.SizeOf(typeof(SIGNER_PROVIDER_INFO)), pwszProviderName = Marshal.StringToHGlobalUni(key.CspKeyContainerInfo.ProviderName), dwProviderType = (uint)key.CspKeyContainerInfo.ProviderType, dwPvkChoice = PVK_TYPE_KEYCONTAINER, Union1 = new SIGNER_PROVIDER_INFO.SignerProviderUnion { pwszKeyContainer = Marshal.StringToHGlobalUni(key.CspKeyContainerInfo.KeyContainerName) }, }; IntPtr pProviderInfo = Marshal.AllocHGlobal(Marshal.SizeOf(providerInfo)); Marshal.StructureToPtr(providerInfo, pProviderInfo, false); return(pProviderInfo); }
private static void SetPrivateKeyProperty(X509Certificate2 certificate, ICspAsymmetricAlgorithm privateKey) { if (_setPrivateKeyPropertyMethod == null) { lock (SetPrivateKeyPropertyMethodSync) { if (_setPrivateKeyPropertyMethod == null) { _setPrivateKeyPropertyMethod = typeof(X509Certificate2).GetMethod("SetPrivateKeyProperty", BindingFlags.Static | BindingFlags.NonPublic); } } } if (_setPrivateKeyPropertyMethod != null) { var certContext = GetCertContext(certificate); if (certContext != null) { try { _setPrivateKeyPropertyMethod.Invoke(null, new[] { certContext, privateKey }); } catch { // ignored } } } }
/// <summary> /// Translates claims to strings /// </summary> /// <param name="claim">Claim to translate to a string</param> /// <returns></returns> public static string GetResourceValue(Claim claim) { string strClaim = claim.Resource as string; if (!string.IsNullOrEmpty(strClaim)) return strClaim; IdentityReference reference = claim.Resource as IdentityReference; if (null != reference) { return reference.Value; } ICspAsymmetricAlgorithm rsa = claim.Resource as ICspAsymmetricAlgorithm; if (null != rsa) { using (SHA256 sha = new SHA256Managed()) { return Convert.ToBase64String(sha.ComputeHash(rsa.ExportCspBlob(false))); } } MailAddress mail = claim.Resource as MailAddress; if (null != mail) { return mail.ToString(); } byte[] bufferValue = claim.Resource as byte[]; if (null != bufferValue) { return Convert.ToBase64String(bufferValue); } return claim.Resource.ToString(); }
private static Func <X509Certificate2, T> BindGetCapiPublicKey <T, TCryptoServiceProvider>(string algorithmOid) where T : AsymmetricAlgorithm where TCryptoServiceProvider : T, ICspAsymmetricAlgorithm, new() { return(cert => { PublicKey publicKeyInfo = cert.PublicKey; if (publicKeyInfo.Oid.Value != algorithmOid) { return null; } AsymmetricAlgorithm publicKey = publicKeyInfo.Key; Debug.Assert(publicKey != null); Debug.Assert(publicKey is T); Debug.Assert(publicKey is ICspAsymmetricAlgorithm); ICspAsymmetricAlgorithm sharedCspKey = (ICspAsymmetricAlgorithm)publicKey; byte[] publicKeyBlob = sharedCspKey.ExportCspBlob(false); TCryptoServiceProvider uniqueCspKey = new TCryptoServiceProvider(); uniqueCspKey.ImportCspBlob(publicKeyBlob); return uniqueCspKey; }); }
private static Func <X509Certificate2, T> BindGetCapiPrivateKey <T>( string algorithmOid, Func <CspParameters, T> instanceFactory) where T : AsymmetricAlgorithm { return(cert => { if (!cert.HasPrivateKey) { return null; } PublicKey publicKeyInfo = cert.PublicKey; if (publicKeyInfo.Oid.Value != algorithmOid) { return null; } AsymmetricAlgorithm privateKey = cert.PrivateKey; Debug.Assert(privateKey != null); Debug.Assert(privateKey is T); Debug.Assert(privateKey is ICspAsymmetricAlgorithm); ICspAsymmetricAlgorithm cspKey = (ICspAsymmetricAlgorithm)privateKey; CspParameters cspParameters = CopyCspParameters(cspKey); return instanceFactory(cspParameters); }); }
private CspKeyContainerInfo GetKeyContainer() { if (!base.HasPrivateKey) { return(null); } AsymmetricAlgorithm asymmetricAlgorithm = null; try { asymmetricAlgorithm = base.PrivateKey; } catch (CryptographicException) { return(null); } if (asymmetricAlgorithm == null) { return(null); } ICspAsymmetricAlgorithm cspAsymmetricAlgorithm = asymmetricAlgorithm as ICspAsymmetricAlgorithm; if (cspAsymmetricAlgorithm == null) { return(null); } return(cspAsymmetricAlgorithm.CspKeyContainerInfo); }
/// <summary> /// Translates claims to strings /// </summary> /// <param name="claim">Claim to translate to a string</param> /// <returns></returns> protected static string GetResourceValue(Claim claim) { IdentityReference reference = claim.Resource as IdentityReference; if (null != reference) { return(reference.Value); } ICspAsymmetricAlgorithm rsa = claim.Resource as ICspAsymmetricAlgorithm; if (null != rsa) { using (SHA256 sha = new SHA256Managed()) { return(Convert.ToBase64String(sha.ComputeHash(rsa.ExportCspBlob(false)))); } } System.Net.Mail.MailAddress mail = claim.Resource as System.Net.Mail.MailAddress; if (null != mail) { return(mail.ToString()); } byte[] bufferValue = claim.Resource as byte[]; if (null != bufferValue) { return(Convert.ToBase64String(bufferValue)); } return(claim.Resource.ToString()); }
/// <summary> /// Initializes a new instance of the <see cref="RSAKey" /> class. /// </summary> /// <param name="csp">The <see cref="RSACryptoServiceProvider"/> to be used.</param> /// <exception cref="System.ArgumentNullException">csp</exception> public RSAKey(ICspAsymmetricAlgorithm csp) { if (csp == null) { throw new ArgumentNullException("csp"); } var publicKey = csp.ExportCspBlob(false); var privateKey = csp.ExportCspBlob(true); Public = Convert.ToBase64String(publicKey); Private = Convert.ToBase64String(privateKey); }
/// <summary> /// Initializes a new instance of the <see cref="RSAKey" /> class. /// </summary> /// <param name="csp">The <see cref="RSACryptoServiceProvider"/> to be used.</param> /// <exception cref="System.ArgumentNullException">csp</exception> public RSAKey(ICspAsymmetricAlgorithm csp) { if(csp == null) { throw new ArgumentNullException("csp"); } var publicKey = csp.ExportCspBlob(false); var privateKey = csp.ExportCspBlob(true); Public = Convert.ToBase64String(publicKey); Private = Convert.ToBase64String(privateKey); }
private bool IsPrivateKeyExportable(X509Certificate2 col1) { bool _exportable = false; try { ICspAsymmetricAlgorithm key = (ICspAsymmetricAlgorithm)col1.PrivateKey; if (key != null) { _exportable = key.CspKeyContainerInfo.Exportable; } } catch { } return(_exportable); }
private static byte[] CalculateSignerPublicKeyToken(AsymmetricAlgorithm key) { Debug.Assert(key != null, "key != null"); ICspAsymmetricAlgorithm cspAlgorithm = key as ICspAsymmetricAlgorithm; if (cspAlgorithm == null) { return(null); } byte[] publicKey = cspAlgorithm.ExportCspBlob(false); SafeAxlBufferHandle tokenBuffer; unsafe { fixed(byte *pPublicKey = publicKey) { // Safe, since we're ensuring the CAPI buffer going in is sized correctly CapiNative.CRYPTOAPI_BLOB keyBlob = new CapiNative.CRYPTOAPI_BLOB(); keyBlob.cbData = publicKey.Length; keyBlob.pbData = new IntPtr(pPublicKey); int hrToken = CapiNative.UnsafeNativeMethods._AxlPublicKeyBlobToPublicKeyToken(ref keyBlob, out tokenBuffer); if (((uint)hrToken & 0x80000000) != 0) { return(null); } } } bool acquired = false; RuntimeHelpers.PrepareConstrainedRegions(); try { tokenBuffer.DangerousAddRef(ref acquired); return(HexStringToBytes(Marshal.PtrToStringUni(tokenBuffer.DangerousGetHandle()))); } finally { if (acquired) { tokenBuffer.DangerousRelease(); } } }
private static CspParameters CopyCspParameters(ICspAsymmetricAlgorithm cspAlgorithm) { CspKeyContainerInfo cspInfo = cspAlgorithm.CspKeyContainerInfo; CspParameters cspParameters = new CspParameters(cspInfo.ProviderType, cspInfo.ProviderName, cspInfo.KeyContainerName) { Flags = CspProviderFlags.UseExistingKey, KeyNumber = (int)cspInfo.KeyNumber, }; if (cspInfo.MachineKeyStore) { cspParameters.Flags |= CspProviderFlags.UseMachineKeyStore; } return(cspParameters); }
/// <summary> /// Map a key to a string describing the key /// </summary> private static string GetKeyName(object key) { Debug.Assert(key != null, "key != null"); ICspAsymmetricAlgorithm cspKey = key as ICspAsymmetricAlgorithm; X509Certificate certificate = key as X509Certificate; X509Certificate2 certificate2 = key as X509Certificate2; // // Use the following sources for key names, if available: // // * CAPI key -> key container name // * X509Certificate2 -> subject simple name // * X509Certificate -> subject name // * All others -> hash code // string keyName = null; if (cspKey != null && cspKey.CspKeyContainerInfo.KeyContainerName != null) { keyName = String.Format(CultureInfo.InvariantCulture, "\"{0}\"", cspKey.CspKeyContainerInfo.KeyContainerName); } else if (certificate2 != null) { keyName = String.Format(CultureInfo.InvariantCulture, "\"{0}\"", certificate2.GetNameInfo(X509NameType.SimpleName, false)); } else if (certificate != null) { keyName = String.Format(CultureInfo.InvariantCulture, "\"{0}\"", certificate.Subject); } else { keyName = key.GetHashCode().ToString("x8", CultureInfo.InvariantCulture); } return(String.Format(CultureInfo.InvariantCulture, "{0}#{1}", key.GetType().Name, keyName)); }
private static unsafe byte[] CalculateSignerPublicKeyToken(AsymmetricAlgorithm key) { SafeAxlBufferHandle handle; byte[] buffer2; ICspAsymmetricAlgorithm algorithm = key as ICspAsymmetricAlgorithm; if (algorithm == null) { return(null); } byte[] buffer = algorithm.ExportCspBlob(false); fixed(byte *numRef = buffer) { CapiNative.CRYPTOAPI_BLOB pCspPublicKeyBlob = new CapiNative.CRYPTOAPI_BLOB { cbData = buffer.Length, pbData = new IntPtr((void *)numRef) }; if ((CapiNative.UnsafeNativeMethods._AxlPublicKeyBlobToPublicKeyToken(ref pCspPublicKeyBlob, out handle) & -2147483648) != 0) { return(null); } } bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { handle.DangerousAddRef(ref success); buffer2 = HexStringToBytes(Marshal.PtrToStringUni(handle.DangerousGetHandle())); } finally { if (success) { handle.DangerousRelease(); } } return(buffer2); }
/// <summary> /// Map a key to a string describing the key /// </summary> private static string GetKeyName(object key) { Debug.Assert(key != null, "key != null"); ICspAsymmetricAlgorithm cspKey = key as ICspAsymmetricAlgorithm; X509Certificate certificate = key as X509Certificate; X509Certificate2 certificate2 = key as X509Certificate2; // // Use the following sources for key names, if available: // // * CAPI key -> key container name // * X509Certificate2 -> subject simple name // * X509Certificate -> subject name // * All others -> hash code // string keyName = null; #pragma warning disable CA1416 // This call site is reachable on all platforms. 'CspKeyContainerInfo.KeyContainerName' is supported on: 'windows'. if (cspKey != null && cspKey.CspKeyContainerInfo.KeyContainerName != null) { keyName = "\"" + cspKey.CspKeyContainerInfo.KeyContainerName + "\""; } #pragma warning restore CA1416 else if (certificate2 != null) { keyName = "\"" + certificate2.GetNameInfo(X509NameType.SimpleName, false) + "\""; } else if (certificate != null) { keyName = "\"" + certificate.Subject + "\""; } else { keyName = key.GetHashCode().ToString("x8", CultureInfo.InvariantCulture); } return($"{key.GetType().Name}#{keyName}"); }
internal static ExchangeCertificateValidity ValidateExchangeCertificate(X509Certificate2 cert, bool ignoreAccessible) { if (cert == null) { throw new ArgumentNullException("cert"); } if (!cert.HasPrivateKey) { return(ExchangeCertificateValidity.PrivateKeyMissing); } string keyAlgorithm = cert.GetKeyAlgorithm(); bool flag = string.Equals(keyAlgorithm, WellKnownOid.X957Sha1Dsa.Value, StringComparison.OrdinalIgnoreCase); if (!string.Equals(keyAlgorithm, WellKnownOid.RsaRsa.Value, StringComparison.OrdinalIgnoreCase) && !flag) { return(ExchangeCertificateValidity.KeyAlgorithmUnsupported); } foreach (X509Extension x509Extension in cert.Extensions) { try { X509KeyUsageExtension x509KeyUsageExtension = x509Extension as X509KeyUsageExtension; if (x509KeyUsageExtension != null) { X509KeyUsageFlags keyUsages = x509KeyUsageExtension.KeyUsages; bool flag2 = false; if (keyUsages == X509KeyUsageFlags.None) { flag2 = true; } else if ((keyUsages & (X509KeyUsageFlags.NonRepudiation | X509KeyUsageFlags.DigitalSignature)) != X509KeyUsageFlags.None) { flag2 = true; } if (!flag2) { return(ExchangeCertificateValidity.SigningNotSupported); } } } catch (CryptographicException) { return(ExchangeCertificateValidity.KeyUsageCorrupted); } try { X509EnhancedKeyUsageExtension x509EnhancedKeyUsageExtension = x509Extension as X509EnhancedKeyUsageExtension; if (x509EnhancedKeyUsageExtension != null && x509EnhancedKeyUsageExtension.EnhancedKeyUsages.Count > 0 && x509EnhancedKeyUsageExtension.EnhancedKeyUsages[WellKnownOid.PkixKpServerAuth.Value] == null) { return(ExchangeCertificateValidity.PkixKpServerAuthNotFoundInEnhancedKeyUsage); } } catch (CryptographicException) { return(ExchangeCertificateValidity.EnhancedKeyUsageCorrupted); } } if (TlsCertificateInfo.IsCNGProvider(cert)) { return(ManageExchangeCertificate.CheckCNGSettings(cert)); } AsymmetricAlgorithm privateKey; try { privateKey = cert.PrivateKey; } catch (CryptographicException) { return(ExchangeCertificateValidity.PrivateKeyNotAccessible); } ICspAsymmetricAlgorithm cspAsymmetricAlgorithm = privateKey as ICspAsymmetricAlgorithm; if (cspAsymmetricAlgorithm == null) { return(ExchangeCertificateValidity.PrivateKeyUnsupportedAlgorithm); } CspKeyContainerInfo cspKeyContainerInfo = cspAsymmetricAlgorithm.CspKeyContainerInfo; if (cspKeyContainerInfo.Protected) { return(ExchangeCertificateValidity.CspKeyContainerInfoProtected); } if (cspKeyContainerInfo.HardwareDevice && cspKeyContainerInfo.Removable) { return(ExchangeCertificateValidity.CspKeyContainerInfoRemovableDevice); } if (!ignoreAccessible && !cspKeyContainerInfo.Accessible) { return(ExchangeCertificateValidity.CspKeyContainerInfoNotAccessible); } switch (cspKeyContainerInfo.KeyNumber) { case KeyNumber.Exchange: case KeyNumber.Signature: { AsymmetricAlgorithm key = cert.PublicKey.Key; if (key.KeySize < 1024) { return(ExchangeCertificateValidity.PublicKeyUnsupportedSize); } return(ExchangeCertificateValidity.Valid); } default: return(ExchangeCertificateValidity.CspKeyContainerInfoUnknownKeyNumber); } }
/// <summary> /// Set the private key object. The additional "publicKey" argument is used to validate that the private key corresponds to the existing publicKey. /// </summary> public void SetPrivateKey(AsymmetricAlgorithm privateKey, AsymmetricAlgorithm publicKey) { if (privateKey == null) { unsafe { if (!Interop.crypt32.CertSetCertificateContextProperty(_certContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, CertSetPropertyFlags.None, (CRYPT_KEY_PROV_INFO *)null)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } } else { // we do not support keys in non-CAPI storage for now. ICspAsymmetricAlgorithm asymmetricAlgorithm = privateKey as ICspAsymmetricAlgorithm; if (asymmetricAlgorithm == null) { throw new NotSupportedException(SR.NotSupported_InvalidKeyImpl); } if (asymmetricAlgorithm.CspKeyContainerInfo == null) { throw new ArgumentException("CspKeyContainerInfo"); } // check that the public key in the certificate corresponds to the private key passed in. // // note that it should be legal to set a key which matches in every aspect but the usage // i.e. to use a CALG_RSA_KEYX private key to match a CALG_RSA_SIGN public key. A // PUBLICKEYBLOB is defined as: // // BLOBHEADER publickeystruc // RSAPUBKEY rsapubkey // BYTE modulus[rsapubkey.bitlen/8] // // To allow keys which differ by key usage only, we skip over the BLOBHEADER of the key, // and start comparing bytes at the RSAPUBKEY structure. unsafe { // This cast is safe because via our contract with our caller, "publicKey" is the Key property of a PublicKey object that this Pal class manufactured in the first place. // Since we manufactured the PublicKey, we know the real types of the object. ICspAsymmetricAlgorithm cspPublicKey = (ICspAsymmetricAlgorithm)publicKey; byte[] array1 = cspPublicKey.ExportCspBlob(false); byte[] array2 = asymmetricAlgorithm.ExportCspBlob(false); if (array1 == null || array2 == null || array1.Length != array2.Length || array1.Length <= sizeof(BLOBHEADER)) { throw new CryptographicUnexpectedOperationException(SR.Cryptography_X509_KeyMismatch); } for (int index = sizeof(BLOBHEADER); index < array1.Length; index++) { if (array1[index] != array2[index]) { throw new CryptographicUnexpectedOperationException(SR.Cryptography_X509_KeyMismatch); } } } unsafe { CspKeyContainerInfo keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo; fixed(char *pKeyContainerName = keyContainerInfo.KeyContainerName, pProviderName = keyContainerInfo.ProviderName) { CRYPT_KEY_PROV_INFO keyProvInfo = new CRYPT_KEY_PROV_INFO() { pwszContainerName = pKeyContainerName, pwszProvName = pProviderName, dwProvType = keyContainerInfo.ProviderType, dwFlags = keyContainerInfo.MachineKeyStore ? CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET : CryptAcquireContextFlags.None, cProvParam = 0, rgProvParam = IntPtr.Zero, dwKeySpec = (int)(keyContainerInfo.KeyNumber), }; if (!Interop.crypt32.CertSetCertificateContextProperty(_certContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, CertSetPropertyFlags.None, &keyProvInfo)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } } } }
private static void SetPrivateKeyProperty(System.Security.Cryptography.SafeCertContextHandle safeCertContextHandle, ICspAsymmetricAlgorithm asymmetricAlgorithm) { SafeLocalAllocHandle invalidHandle = SafeLocalAllocHandle.InvalidHandle; if (asymmetricAlgorithm != null) { CAPIBase.CRYPT_KEY_PROV_INFO structure = new CAPIBase.CRYPT_KEY_PROV_INFO { pwszContainerName = asymmetricAlgorithm.CspKeyContainerInfo.KeyContainerName, pwszProvName = asymmetricAlgorithm.CspKeyContainerInfo.ProviderName, dwProvType = (uint) asymmetricAlgorithm.CspKeyContainerInfo.ProviderType, dwFlags = asymmetricAlgorithm.CspKeyContainerInfo.MachineKeyStore ? 0x20 : 0, cProvParam = 0, rgProvParam = IntPtr.Zero, dwKeySpec = (uint) asymmetricAlgorithm.CspKeyContainerInfo.KeyNumber }; invalidHandle = CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(CAPIBase.CRYPT_KEY_PROV_INFO)))); Marshal.StructureToPtr(structure, invalidHandle.DangerousGetHandle(), false); } try { if (!CAPI.CertSetCertificateContextProperty(safeCertContextHandle, 2, 0, invalidHandle)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } finally { if (!invalidHandle.IsInvalid) { Marshal.DestroyStructure(invalidHandle.DangerousGetHandle(), typeof(CAPIBase.CRYPT_KEY_PROV_INFO)); invalidHandle.Dispose(); } } }
private static unsafe void SetPrivateKeyProperty (SafeCertContextHandle safeCertContextHandle, ICspAsymmetricAlgorithm asymmetricAlgorithm) { SafeLocalAllocHandle ptr = SafeLocalAllocHandle.InvalidHandle; if (asymmetricAlgorithm != null) { CAPI.CRYPT_KEY_PROV_INFO keyProvInfo = new CAPI.CRYPT_KEY_PROV_INFO(); keyProvInfo.pwszContainerName = asymmetricAlgorithm.CspKeyContainerInfo.KeyContainerName; keyProvInfo.pwszProvName = asymmetricAlgorithm.CspKeyContainerInfo.ProviderName; keyProvInfo.dwProvType = (uint) asymmetricAlgorithm.CspKeyContainerInfo.ProviderType; keyProvInfo.dwFlags = asymmetricAlgorithm.CspKeyContainerInfo.MachineKeyStore ? CAPI.CRYPT_MACHINE_KEYSET : 0; keyProvInfo.cProvParam = 0; keyProvInfo.rgProvParam = IntPtr.Zero; keyProvInfo.dwKeySpec = (uint) asymmetricAlgorithm.CspKeyContainerInfo.KeyNumber; ptr = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_KEY_PROV_INFO)))); Marshal.StructureToPtr(keyProvInfo, ptr.DangerousGetHandle(), false); } try { if (!CAPI.CertSetCertificateContextProperty(safeCertContextHandle, CAPI.CERT_KEY_PROV_INFO_PROP_ID, 0, ptr)) throw new CryptographicException(Marshal.GetLastWin32Error()); } finally { if (!ptr.IsInvalid) { Marshal.DestroyStructure(ptr.DangerousGetHandle(), typeof(CAPI.CRYPT_KEY_PROV_INFO)); ptr.Dispose(); } } }
private static void SetPrivateKeyProperty(System.Security.Cryptography.SafeCertContextHandle safeCertContextHandle, ICspAsymmetricAlgorithm asymmetricAlgorithm) { SafeLocalAllocHandle invalidHandle = SafeLocalAllocHandle.InvalidHandle; if (asymmetricAlgorithm != null) { CAPIBase.CRYPT_KEY_PROV_INFO structure = new CAPIBase.CRYPT_KEY_PROV_INFO { pwszContainerName = asymmetricAlgorithm.CspKeyContainerInfo.KeyContainerName, pwszProvName = asymmetricAlgorithm.CspKeyContainerInfo.ProviderName, dwProvType = (uint)asymmetricAlgorithm.CspKeyContainerInfo.ProviderType, dwFlags = asymmetricAlgorithm.CspKeyContainerInfo.MachineKeyStore ? 0x20 : 0, cProvParam = 0, rgProvParam = IntPtr.Zero, dwKeySpec = (uint)asymmetricAlgorithm.CspKeyContainerInfo.KeyNumber }; invalidHandle = CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(CAPIBase.CRYPT_KEY_PROV_INFO)))); Marshal.StructureToPtr(structure, invalidHandle.DangerousGetHandle(), false); } try { if (!CAPI.CertSetCertificateContextProperty(safeCertContextHandle, 2, 0, invalidHandle)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } finally { if (!invalidHandle.IsInvalid) { Marshal.DestroyStructure(invalidHandle.DangerousGetHandle(), typeof(CAPIBase.CRYPT_KEY_PROV_INFO)); invalidHandle.Dispose(); } } }
/////////////////////////////////////////////////////////////////////// /// /// <summary> /// Carry out the Sign command. /// </summary> /// static void DoSignCommand(string title, X509Certificate2 certificate) { Console.WriteLine(); Console.WriteLine("Signing Xml file \"" + fileNames[0] + "\"..."); Console.WriteLine(); // display more details for verbose operation. if (verbose) { DisplayDetail(null, certificate, detached); } SignedXml signedXml = new SignedXml(); ICspAsymmetricAlgorithm csp = (ICspAsymmetricAlgorithm)certificate.PrivateKey; if (csp.CspKeyContainerInfo.RandomlyGenerated) { throw new InternalException("Internal error: This certificate does not have a corresponding private key."); } signedXml.SigningKey = (AsymmetricAlgorithm)csp; Console.WriteLine(signedXml.SigningKey.ToXmlString(false)); if (detached) { Reference reference = new Reference(); reference.Uri = "file://" + Path.GetFullPath((string)fileNames[0]); signedXml.AddReference(reference); } else { Reference reference = new Reference(); reference.Uri = "#object-1"; // Add an object XmlDocument dataObject = new XmlDocument(); dataObject.PreserveWhitespace = true; XmlElement dataElement = (XmlElement)dataObject.CreateElement("DataObject", SignedXml.XmlDsigNamespaceUrl); dataElement.AppendChild(dataObject.CreateTextNode(new UTF8Encoding(false).GetString(ReadFile((string)fileNames[0])))); dataObject.AppendChild(dataElement); DataObject obj = new DataObject(); obj.Data = dataObject.ChildNodes; obj.Id = "object-1"; signedXml.AddObject(obj); signedXml.AddReference(reference); } signedXml.KeyInfo = new KeyInfo(); if (includeOptions.Count == 0) { signedXml.KeyInfo.AddClause(new KeyInfoX509Data(certificate, X509IncludeOption.ExcludeRoot)); } else { KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(); foreach (IncludeOptions includeOption in includeOptions) { switch (includeOption) { case IncludeOptions.ExcludeRoot: case IncludeOptions.EndCertOnly: case IncludeOptions.WholeChain: keyInfoX509Data = new KeyInfoX509Data(certificate, (X509IncludeOption)includeOption); break; case IncludeOptions.SubjectName: keyInfoX509Data.AddSubjectName(certificate.SubjectName.Name); break; case IncludeOptions.SKI: X509ExtensionCollection extensions = certificate.Extensions; foreach (X509Extension extension in extensions) { if (extension.Oid.Value == "2.5.29.14") // OID for SKI extension { X509SubjectKeyIdentifierExtension ski = extension as X509SubjectKeyIdentifierExtension; if (ski != null) { keyInfoX509Data.AddSubjectKeyId(ski.SubjectKeyIdentifier); break; } } } break; case IncludeOptions.IssuerSerial: keyInfoX509Data.AddIssuerSerial(certificate.IssuerName.Name, certificate.SerialNumber); break; } signedXml.KeyInfo.AddClause(keyInfoX509Data); } } // compute the signature signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); // write it out XmlTextWriter xmltw = new XmlTextWriter((string)fileNames[1], new UTF8Encoding(false)); xmlDigitalSignature.WriteTo(xmltw); xmltw.Close(); Console.WriteLine(); Console.WriteLine("Signature written to file \"" + fileNames[1] + "\"."); Console.WriteLine(); return; }