コード例 #1
0
ファイル: CorePsStub.cs プロジェクト: 40a/PowerShell
 internal static string Encrypt(byte[] contentBytes, CmsMessageRecipient[] recipients, SessionState sessionState, out ErrorRecord error)
 {
     throw new NotImplementedException("CmsUtils.Encrypt(...) is not implemented in CoreCLR powershell.");
 }
コード例 #2
0
ファイル: CompiledScriptBlock.cs プロジェクト: 40a/PowerShell
        private static bool GetAndValidateEncryptionRecipients(ScriptBlock scriptBlock)
        {
            Dictionary<string, object> protectedEventLoggingSettings = Utils.GetGroupPolicySetting(
                "Software\\Policies\\Microsoft\\Windows\\EventLog", "ProtectedEventLogging", Utils.RegLocalMachine);

            // See if protected event logging is enabled
            object enableProtectedEventLogging = null;
            if (protectedEventLoggingSettings.TryGetValue("EnableProtectedEventLogging", out enableProtectedEventLogging))
            {
                if (String.Equals("1", enableProtectedEventLogging.ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    // Get the encryption certificate
                    object encryptionCertificate = null;
                    if (protectedEventLoggingSettings.TryGetValue("EncryptionCertificate", out encryptionCertificate))
                    {
                        ErrorRecord error = null;
                        ExecutionContext executionContext = LocalPipeline.GetExecutionContextFromTLS();
                        SessionState sessionState = null;

                        // Use the session state from the current pipeline, if it exists.
                        if (executionContext != null)
                        {
                            sessionState = executionContext.SessionState;
                        }

                        // If the engine hasn't started up yet, then we're just compiling script
                        // blocks. We'll have to log them when they are used and we have an engine
                        // to work with.
                        if (sessionState == null)
                        {
                            return false;
                        }

                        string[] encryptionCertificateContent = encryptionCertificate as string[];
                        string fullCertificateContent = null;
                        if (encryptionCertificateContent != null)
                        {
                            fullCertificateContent = String.Join(Environment.NewLine, encryptionCertificateContent);
                        }
                        else
                        {
                            fullCertificateContent = encryptionCertificate as string;
                        }

                        // If the certificate has changed, drop all of our cached information
                        ResetCertificateCacheIfNeeded(fullCertificateContent);

                        // If we have valid recipients, no need for further analysis.
                        if (s_encryptionRecipients != null)
                        {
                            return true;
                        }

                        // If we've already verified all of the properties of the cert we care about (even if it
                        // didn't result in a valid cert), return now.
                        if (s_hasProcessedCertificate)
                        {
                            return true;
                        }

                        // Resolve the certificate to a recipient
                        CmsMessageRecipient recipient = new CmsMessageRecipient(fullCertificateContent);
                        recipient.Resolve(sessionState, ResolutionPurpose.Encryption, out error);
                        s_hasProcessedCertificate = true;

                        // If there's an error that we haven't already reported, report it in the event log.
                        // We only do this once, as the error will always be the same for a given certificate.
                        if (error != null)
                        {
                            // If we got an error resolving the encryption certificate, log a warning and continue
                            // logging the (unencrypted) message anyways. Logging trumps protected logging -
                            // being able to detect that an attacker has compromised a box outweighs the danger of the
                            // attacker seeing potentially sensitive data. Because if they aren't detected, then
                            // they can just wait on the compromised box and see the sensitive data eventually anyways.
                            string errorMessage = StringUtil.Format(SecuritySupportStrings.CouldNotUseCertificate, error.ToString());
                            PSEtwLog.LogOperationalError(PSEventId.ScriptBlock_Compile_Detail, PSOpcode.Create, PSTask.ExecuteCommand, PSKeyword.UseAlwaysAnalytic,
                                            0, 0, errorMessage, scriptBlock.Id.ToString(), scriptBlock.File ?? String.Empty);

                            return true;
                        }

                        // Now, save the certificate. We'll be comfortable using this one from now on.
                        s_encryptionRecipients = new CmsMessageRecipient[] { recipient };

                        // Check if the certificate has a private key, and report a warning if so.
                        // We only do this once, as the error will always be the same for a given certificate.
                        foreach (X509Certificate2 validationCertificate in recipient.Certificates)
                        {
                            if (validationCertificate.HasPrivateKey)
                            {
                                // Only log the first line of what we pulled from the registry. If this is a path, this will have enough information.
                                // If this is the actual certificate, only include the first line of the certificate content so that we're not permanently keeping the private
                                // key in the log.
                                string certificateForLog = fullCertificateContent;
                                if ((encryptionCertificateContent != null) && (encryptionCertificateContent.Length > 1))
                                {
                                    certificateForLog = encryptionCertificateContent[1];
                                }

                                string errorMessage = StringUtil.Format(SecuritySupportStrings.CertificateContainsPrivateKey, certificateForLog);
                                PSEtwLog.LogOperationalError(PSEventId.ScriptBlock_Compile_Detail, PSOpcode.Create, PSTask.ExecuteCommand, PSKeyword.UseAlwaysAnalytic,
                                                0, 0, errorMessage, scriptBlock.Id.ToString(), scriptBlock.File ?? String.Empty);
                            }
                        }
                    }
                }
            }

            return true;
        }
コード例 #3
0
ファイル: SecuritySupport.cs プロジェクト: 40a/PowerShell
        internal static string Encrypt(byte[] contentBytes, CmsMessageRecipient[] recipients, SessionState sessionState, out ErrorRecord error)
        {
            error = null;

            if ((contentBytes == null) || (contentBytes.Length == 0))
            {
                return String.Empty;
            }

            // After review with the crypto board, NIST_AES256_CBC is more appropriate
            // than .NET's default 3DES. Also, when specified, uses szOID_RSAES_OAEP for key
            // encryption to prevent padding attacks.
            const string szOID_NIST_AES256_CBC = "2.16.840.1.101.3.4.1.42";

            ContentInfo content = new ContentInfo(contentBytes);
            EnvelopedCms cms = new EnvelopedCms(content,
                new AlgorithmIdentifier(
                    Oid.FromOidValue(szOID_NIST_AES256_CBC, OidGroup.EncryptionAlgorithm)));

            CmsRecipientCollection recipientCollection = new CmsRecipientCollection();
            foreach (CmsMessageRecipient recipient in recipients)
            {
                // Resolve the recipient, if it hasn't been done yet.
                if ((recipient.Certificates != null) && (recipient.Certificates.Count == 0))
                {
                    recipient.Resolve(sessionState, ResolutionPurpose.Encryption, out error);
                }

                if (error != null)
                {
                    return null;
                }

                foreach (X509Certificate2 certificate in recipient.Certificates)
                {
                    recipientCollection.Add(new CmsRecipient(certificate));
                }
            }

            cms.Encrypt(recipientCollection);

            byte[] encodedBytes = cms.Encode();
            string encodedContent = CmsUtils.GetAsciiArmor(encodedBytes);
            return encodedContent;
        }