MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Diagnostics.CodeAnalysis;6using System.Management.Automation;7using System.Security;8using System.Security.Cryptography;9using System.Security.Cryptography.X509Certificates;10 11using Dbg = System.Management.Automation.Diagnostics;12 13namespace Microsoft.PowerShell.Commands14{15 /// <summary>16 /// Defines the implementation of the get-pfxcertificate cmdlet.17 /// </summary>18 [Cmdlet(VerbsCommon.Get, "PfxCertificate", DefaultParameterSetName = "ByPath", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096918")]19 [OutputType(typeof(X509Certificate2))]20 public sealed class GetPfxCertificateCommand : PSCmdlet21 {22 /// <summary>23 /// Gets or sets the path of the item for which to obtain the24 /// certificate.25 /// </summary>26 [Parameter(Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, Mandatory = true, ParameterSetName = "ByPath")]27 public string[] FilePath28 {29 get30 {31 return _path;32 }33 34 set35 {36 _path = value;37 }38 }39 40 private string[] _path;41 42 /// <summary>43 /// Gets or sets the literal path of the item for which to obtain the44 /// certificate.45 /// </summary>46 [Parameter(ValueFromPipelineByPropertyName = true, Mandatory = true, ParameterSetName = "ByLiteralPath")]47 [Alias("PSPath", "LP")]48 [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]49 public string[] LiteralPath50 {51 get52 {53 return _path;54 }55 56 set57 {58 _path = value;59 _isLiteralPath = true;60 }61 }62 63 private bool _isLiteralPath = false;64 65 /// <summary>66 /// Gets or sets the password for unlocking the certificate.67 /// </summary>68 [Parameter(Mandatory = false)]69 public SecureString Password { get; set; }70 71 /// <summary>72 /// Do not prompt for password if not given.73 /// </summary>74 [Parameter(Mandatory = false)]75 public SwitchParameter NoPromptForPassword { get; set; }76 77 //78 // list of files that were not found79 //80 private readonly List<string> _filesNotFound = new();81 82 /// <summary>83 /// Initializes a new instance of the GetPfxCertificateCommand84 /// class.85 /// </summary>86 public GetPfxCertificateCommand() : base()87 {88 }89 90 /// <summary>91 /// Processes records from the input pipeline.92 /// For each input file, the command retrieves its93 /// corresponding certificate.94 /// </summary>95 protected override void ProcessRecord()96 {97 //98 // this cannot happen as we have specified the Path99 // property to be a mandatory parameter100 //101 Dbg.Assert((FilePath != null) && (FilePath.Length > 0),102 "GetCertificateCommand: Param binder did not bind path");103 104 X509Certificate2 cert = null;105 106 foreach (string p in FilePath)107 {108 List<string> paths = new();109 110 // Expand wildcard characters111 if (_isLiteralPath)112 {113 paths.Add(SessionState.Path.GetUnresolvedProviderPathFromPSPath(p));114 }115 else116 {117 try118 {119 foreach (PathInfo tempPath in SessionState.Path.GetResolvedPSPathFromPSPath(p))120 {121 paths.Add(tempPath.ProviderPath);122 }123 }124 catch (ItemNotFoundException)125 {126 _filesNotFound.Add(p);127 }128 }129 130 foreach (string resolvedPath in paths)131 {132 string resolvedProviderPath =133 SecurityUtils.GetFilePathOfExistingFile(this, resolvedPath);134 135 if (resolvedProviderPath == null)136 {137 _filesNotFound.Add(p);138 }139 else140 {141 if (Password == null && !NoPromptForPassword.IsPresent)142 {143 try144 {145 cert = GetCertFromPfxFile(resolvedProviderPath, null);146 WriteObject(cert);147 continue;148 }149 catch (CryptographicException)150 {151 Password = SecurityUtils.PromptForSecureString(152 Host.UI,153 CertificateCommands.GetPfxCertPasswordPrompt);154 }155 }156 157 try158 {159 cert = GetCertFromPfxFile(resolvedProviderPath, Password);160 }161 catch (CryptographicException e)162 {163 ErrorRecord er = new(164 e,165 "GetPfxCertificateUnknownCryptoError",166 ErrorCategory.NotSpecified,167 targetObject: null);168 WriteError(er);169 continue;170 }171 172 WriteObject(cert);173 }174 }175 }176 177 if (_filesNotFound.Count > 0)178 {179 if (_filesNotFound.Count == FilePath.Length)180 {181 ErrorRecord er =182 SecurityUtils.CreateFileNotFoundErrorRecord(183 CertificateCommands.NoneOfTheFilesFound,184 "GetPfxCertCommandNoneOfTheFilesFound");185 186 ThrowTerminatingError(er);187 }188 else189 {190 //191 // we found some files but not others.192 // Write error for each missing file193 //194 foreach (string f in _filesNotFound)195 {196 ErrorRecord er =197 SecurityUtils.CreateFileNotFoundErrorRecord(198 CertificateCommands.FileNotFound,199 "GetPfxCertCommandFileNotFound",200 f201 );202 203 WriteError(er);204 }205 }206 }207 }208 209 private static X509Certificate2 GetCertFromPfxFile(string path, SecureString password)210 {211 // No overload found in X509CertificateLoader that takes SecureString212 #pragma warning disable SYSLIB0057213 var cert = new X509Certificate2(path, password, X509KeyStorageFlags.DefaultKeySet);214 return cert;215 #pragma warning restore SYSLIB0057216 }217 }218}219 