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);
        }
Example #2
0
        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);
        }
Example #3
0
        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));
 }
Example #6
0
        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);
                    }
                }
            }
        }
Example #7
0
        /// <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());
            }
        }
Example #8
0
        /// <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));
                }
            }
        }
Example #9
0
        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>";
        }