IList <Claim> InitializeClaimsCore() { List <Claim> claims = new List <Claim>(); byte[] thumbprint = this.certificate.GetCertHash(); claims.Add(new Claim(ClaimTypes.Thumbprint, thumbprint, Rights.Identity)); claims.Add(new Claim(ClaimTypes.Thumbprint, thumbprint, Rights.PossessProperty)); // Ordering SubjectName, Dns, SimpleName, Email, Upn string value = this.certificate.SubjectName.Name; if (!string.IsNullOrEmpty(value)) { claims.Add(Claim.CreateX500DistinguishedNameClaim(this.certificate.SubjectName)); } claims.AddRange(GetDnsClaims(this.certificate)); value = this.certificate.GetNameInfo(X509NameType.SimpleName, false); if (!string.IsNullOrEmpty(value)) { claims.Add(Claim.CreateNameClaim(value)); } value = this.certificate.GetNameInfo(X509NameType.EmailName, false); if (!string.IsNullOrEmpty(value)) { claims.Add(Claim.CreateMailAddressClaim(new MailAddress(value))); } value = this.certificate.GetNameInfo(X509NameType.UpnName, false); if (!string.IsNullOrEmpty(value)) { claims.Add(Claim.CreateUpnClaim(value)); } value = this.certificate.GetNameInfo(X509NameType.UrlName, false); if (!string.IsNullOrEmpty(value)) { claims.Add(Claim.CreateUriClaim(new Uri(value))); } RSA rsa; if (LocalAppContextSwitches.DisableCngCertificates) { rsa = this.certificate.PublicKey.Key as RSA; } else { rsa = CngLightup.GetRSAPublicKey(this.certificate); } if (rsa != null) { claims.Add(Claim.CreateRsaClaim(rsa)); } return(claims); }
internal static RSA EnsureAndGetPrivateRSAKey(X509Certificate2 certificate) { Fx.Assert(certificate != null, "certificate != null"); // Reject no private key if (!certificate.HasPrivateKey) { #pragma warning suppress 56526 // no validation necessary for value.Thumbprint throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ID1001, certificate.Thumbprint))); } // Check for accessibility of private key RSA rsa; try { if (LocalAppContextSwitches.DisableCngCertificates) { rsa = certificate.PrivateKey as RSA; } else { rsa = CngLightup.GetRSAPrivateKey(certificate); } } catch (CryptographicException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ID1039, certificate.Thumbprint), e)); } if (rsa == null) { #pragma warning suppress 56526 // no validation necessary for value.Thumbprint throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ID1002, certificate.Thumbprint))); } return(rsa); }
public static IEnumerable <Claim> GetClaimsFromCertificate(X509Certificate2 certificate, string issuer) { if (certificate == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("certificate"); } ICollection <Claim> claimsCollection = new Collection <Claim>(); string thumbprint = Convert.ToBase64String(certificate.GetCertHash()); claimsCollection.Add(new Claim(ClaimTypes.Thumbprint, thumbprint, ClaimValueTypes.Base64Binary, issuer)); string value = certificate.SubjectName.Name; if (!string.IsNullOrEmpty(value)) { claimsCollection.Add(new Claim(ClaimTypes.X500DistinguishedName, value, ClaimValueTypes.String, issuer)); } value = certificate.GetNameInfo(X509NameType.DnsName, false); if (!string.IsNullOrEmpty(value)) { claimsCollection.Add(new Claim(ClaimTypes.Dns, value, ClaimValueTypes.String, issuer)); } value = certificate.GetNameInfo(X509NameType.SimpleName, false); if (!string.IsNullOrEmpty(value)) { claimsCollection.Add(new Claim(ClaimTypes.Name, value, ClaimValueTypes.String, issuer)); } value = certificate.GetNameInfo(X509NameType.EmailName, false); if (!string.IsNullOrEmpty(value)) { claimsCollection.Add(new Claim(ClaimTypes.Email, value, ClaimValueTypes.String, issuer)); } value = certificate.GetNameInfo(X509NameType.UpnName, false); if (!string.IsNullOrEmpty(value)) { claimsCollection.Add(new Claim(ClaimTypes.Upn, value, ClaimValueTypes.String, issuer)); } value = certificate.GetNameInfo(X509NameType.UrlName, false); if (!string.IsNullOrEmpty(value)) { claimsCollection.Add(new Claim(ClaimTypes.Uri, value, ClaimValueTypes.String, issuer)); } RSA rsa; if (LocalAppContextSwitches.DisableCngCertificates) { rsa = certificate.PublicKey.Key as RSA; } else { rsa = CngLightup.GetRSAPublicKey(certificate); } if (rsa != null) { claimsCollection.Add(new Claim(ClaimTypes.Rsa, rsa.ToXmlString(false), ClaimValueTypes.RsaKeyValue, issuer)); } DSA dsa; if (LocalAppContextSwitches.DisableCngCertificates) { dsa = certificate.PublicKey.Key as DSA; } else { dsa = CngLightup.GetDSAPublicKey(certificate); } if (dsa != null) { claimsCollection.Add(new Claim(ClaimTypes.Dsa, dsa.ToXmlString(false), ClaimValueTypes.DsaKeyValue, issuer)); } value = certificate.SerialNumber; if (!string.IsNullOrEmpty(value)) { claimsCollection.Add(new Claim(ClaimTypes.SerialNumber, value, ClaimValueTypes.String, issuer)); } return(claimsCollection); }
public static DSA GetDSAPrivateKey(this X509Certificate2 certificate) { return(CngLightup.GetDSAPrivateKey(certificate)); }
public static RSA GetRSAPublicKey(this X509Certificate2 certificate) { return(CngLightup.GetRSAPublicKey(certificate)); }
private static void SignFileInternal(X509Certificate2 cert, Uri timestampUrl, string path, bool targetFrameworkSupportsSha256, System.Resources.ResourceManager resources) { if (cert == null) { throw new ArgumentNullException(nameof(cert)); } if (String.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } if (!FileSystems.Default.FileExists(path)) { throw new FileNotFoundException(String.Format(CultureInfo.InvariantCulture, resources.GetString("SecurityUtil.SignTargetNotFound"), path), path); } bool useSha256 = UseSha256Algorithm(cert) && targetFrameworkSupportsSha256; if (PathUtil.IsPEFile(path)) { if (IsCertInStore(cert)) { SignPEFile(cert, timestampUrl, path, resources, useSha256); } else { throw new InvalidOperationException(resources.GetString("SignFile.CertNotInStore")); } } else { using (RSA rsa = CngLightup.GetRSAPrivateKey(cert)) { if (rsa == null) { throw new ApplicationException(resources.GetString("SecurityUtil.OnlyRSACertsAreAllowed")); } try { var doc = new XmlDocument { PreserveWhitespace = true }; var xrSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }; using (XmlReader xr = XmlReader.Create(path, xrSettings)) { doc.Load(xr); } var manifest = new SignedCmiManifest2(doc, useSha256); CmiManifestSigner2 signer; if (useSha256 && rsa is RSACryptoServiceProvider) { RSACryptoServiceProvider csp = SignedCmiManifest2.GetFixedRSACryptoServiceProvider(rsa as RSACryptoServiceProvider, useSha256); signer = new CmiManifestSigner2(csp, cert, useSha256); } else { signer = new CmiManifestSigner2(rsa, cert, useSha256); } if (timestampUrl == null) { manifest.Sign(signer); } else { manifest.Sign(signer, timestampUrl.ToString()); } doc.Save(path); } catch (Exception ex) { int exceptionHR = Marshal.GetHRForException(ex); if (exceptionHR == -2147012889 || exceptionHR == -2147012867) { throw new ApplicationException(resources.GetString("SecurityUtil.TimestampUrlNotFound"), ex); } throw new ApplicationException(ex.Message, ex); } } } }
/// <summary> /// Encode the data. The data is encrypted using the default encryption algorithm (AES-256), /// then the AES key is encrypted using RSA and the RSA public key is appended. /// </summary> /// <param name="value">The data to encode</param> /// <exception cref="ArgumentNullException">The argument 'value' is null.</exception> /// <exception cref="ArgumentException">The argument 'value' contains zero bytes.</exception> /// <exception cref="InvalidOperationException">The EncryptionKey is null.</exception> /// <returns>Encoded data</returns> public override byte[] Encode(byte[] value) { if (null == value) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); } if (0 == value.Length) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.ID6044)); } RSA encryptionKey = EncryptionKey; if (null == encryptionKey) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6043)); } byte[] rsaHash; byte[] encryptedKeyAndIV; byte[] encryptedData; using (HashAlgorithm hash = CryptoHelper.CreateHashAlgorithm(_hashName)) { rsaHash = hash.ComputeHash(Encoding.UTF8.GetBytes(encryptionKey.ToXmlString(false))); } using (SymmetricAlgorithm encryptionAlgorithm = CryptoHelper.NewDefaultEncryption()) { encryptionAlgorithm.GenerateIV(); encryptionAlgorithm.GenerateKey(); using (ICryptoTransform encryptor = encryptionAlgorithm.CreateEncryptor()) { encryptedData = encryptor.TransformFinalBlock(value, 0, value.Length); } RSACryptoServiceProvider provider = encryptionKey as RSACryptoServiceProvider; if (provider == null) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6041)); } // // Concatenate the Key and IV in an attempt to avoid two minimum block lengths in the cookie // byte[] keyAndIV = new byte[encryptionAlgorithm.Key.Length + encryptionAlgorithm.IV.Length]; Array.Copy(encryptionAlgorithm.Key, keyAndIV, encryptionAlgorithm.Key.Length); Array.Copy(encryptionAlgorithm.IV, 0, keyAndIV, encryptionAlgorithm.Key.Length, encryptionAlgorithm.IV.Length); encryptedKeyAndIV = CngLightup.OaepSha1Encrypt(encryptionKey, keyAndIV); } using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write(rsaHash); bw.Write(encryptedKeyAndIV.Length); bw.Write(encryptedKeyAndIV); bw.Write(encryptedData.Length); bw.Write(encryptedData); bw.Flush(); } return(ms.ToArray()); } }
/// <summary> /// Decrypts data using the provided RSA key(s) to decrypt an AES key, which decrypts the cookie. /// </summary> /// <param name="encoded">The encoded data</param> /// <returns>The decoded data</returns> /// <exception cref="ArgumentNullException">The argument 'encoded' is null.</exception> /// <exception cref="ArgumentException">The argument 'encoded' contains zero bytes.</exception> /// <exception cref="NotSupportedException">The platform does not support the requested algorithm.</exception> /// <exception cref="InvalidOperationException">There are no decryption keys or none of the keys match.</exception> public override byte[] Decode(byte[] encoded) { if (null == encoded) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encoded"); } if (0 == encoded.Length) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("encoded", SR.GetString(SR.ID6045)); } ReadOnlyCollection <RSA> decryptionKeys = DecryptionKeys; if (0 == decryptionKeys.Count) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6039)); } byte[] encryptedKeyAndIV; byte[] encryptedData; byte[] rsaHash; RSA rsaDecryptionKey = null; using (HashAlgorithm hash = CryptoHelper.CreateHashAlgorithm(_hashName)) { int hashSizeInBytes = hash.HashSize / 8; using (BinaryReader br = new BinaryReader(new MemoryStream(encoded))) { rsaHash = br.ReadBytes(hashSizeInBytes); int encryptedKeyAndIVSize = br.ReadInt32(); if (encryptedKeyAndIVSize < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1006, encryptedKeyAndIVSize))); } // // Enforce upper limit on key size to prevent large buffer allocation in br.ReadBytes() // if (encryptedKeyAndIVSize > encoded.Length) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1007))); } encryptedKeyAndIV = br.ReadBytes(encryptedKeyAndIVSize); int encryptedDataSize = br.ReadInt32(); if (encryptedDataSize < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1008, encryptedDataSize))); } // // Enforce upper limit on data size to prevent large buffer allocation in br.ReadBytes() // if (encryptedDataSize > encoded.Length) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1009))); } encryptedData = br.ReadBytes(encryptedDataSize); } // // Find the decryption key matching the one in XML // foreach (RSA key in decryptionKeys) { byte[] hashedKey = hash.ComputeHash(Encoding.UTF8.GetBytes(key.ToXmlString(false))); if (CryptoHelper.IsEqual(hashedKey, rsaHash)) { rsaDecryptionKey = key; break; } } } if (rsaDecryptionKey == null) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6040)); } byte[] decryptedKeyAndIV = CngLightup.OaepSha1Decrypt(rsaDecryptionKey, encryptedKeyAndIV); using (SymmetricAlgorithm symmetricAlgorithm = CryptoHelper.NewDefaultEncryption()) { byte[] decryptionKey = new byte[symmetricAlgorithm.KeySize / 8]; // // Ensure there is sufficient length in the descrypted key and IV buffer for an IV. // if (decryptedKeyAndIV.Length < decryptionKey.Length) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6047, decryptedKeyAndIV.Length, decryptionKey.Length)); } byte[] decryptionIV = new byte[decryptedKeyAndIV.Length - decryptionKey.Length]; // // Copy key into its own buffer. // The remaining bytes are the IV copy those into a buffer as well. // Array.Copy(decryptedKeyAndIV, decryptionKey, decryptionKey.Length); Array.Copy(decryptedKeyAndIV, decryptionKey.Length, decryptionIV, 0, decryptionIV.Length); using (ICryptoTransform decryptor = symmetricAlgorithm.CreateDecryptor(decryptionKey, decryptionIV)) { return(decryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length)); } } }
private static void AuthenticodeSignLicenseDom(XmlDocument licenseDom, CmiManifestSigner2 signer, string timeStampUrl, bool useSha256) { // Make sure it is RSA, as this is the only one Fusion will support. RSA rsaPrivateKey = CngLightup.GetRSAPrivateKey(signer.Certificate); if (rsaPrivateKey == null) { throw new NotSupportedException(); } // Setup up XMLDSIG engine. ManifestSignedXml2 signedXml = new ManifestSignedXml2(licenseDom); // only needs to change the provider type when RSACryptoServiceProvider is used var rsaCsp = rsaPrivateKey is RSACryptoServiceProvider? GetFixedRSACryptoServiceProvider(rsaPrivateKey as RSACryptoServiceProvider, useSha256) : rsaPrivateKey; signedXml.SigningKey = rsaCsp; signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; if (signer.UseSha256) { signedXml.SignedInfo.SignatureMethod = Sha256SignatureMethodUri; } else { signedXml.SignedInfo.SignatureMethod = Sha1SignatureMethodUri; } // Add the key information. signedXml.KeyInfo.AddClause(new RSAKeyValue(rsaCsp)); signedXml.KeyInfo.AddClause(new KeyInfoX509Data(signer.Certificate, signer.IncludeOption)); // Add the enveloped reference. Reference reference = new Reference(); reference.Uri = ""; if (signer.UseSha256) { reference.DigestMethod = Sha256DigestMethod; } else { reference.DigestMethod = Sha1DigestMethod; } // Add an enveloped and an Exc-C14N transform. reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); #if (false) // BUGBUG: LTA transform complaining about issuer node not found. reference.AddTransform(new XmlLicenseTransform()); #endif reference.AddTransform(new XmlDsigExcC14NTransform()); // Add the reference. signedXml.AddReference(reference); // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation XmlElement xmlDigitalSignature = signedXml.GetXml(); xmlDigitalSignature.SetAttribute("Id", "AuthenticodeSignature"); // Insert the signature node under the issuer element. XmlNamespaceManager nsm = new XmlNamespaceManager(licenseDom.NameTable); nsm.AddNamespace("r", LicenseNamespaceUri); XmlElement issuerNode = licenseDom.SelectSingleNode("r:license/r:issuer", nsm) as XmlElement; issuerNode.AppendChild(licenseDom.ImportNode(xmlDigitalSignature, true)); // Time stamp it if requested. if (timeStampUrl != null && timeStampUrl.Length != 0) { TimestampSignedLicenseDom(licenseDom, timeStampUrl); } // Wrap it inside a RelData element. licenseDom.DocumentElement.ParentNode.InnerXml = "<msrel:RelData xmlns:msrel=\"" + MSRelNamespaceUri + "\">" + licenseDom.OuterXml + "</msrel:RelData>"; }