public override AmazonWebServiceResponse Unmarshall(XmlUnmarshallerContext context) { GetPasswordDataResponse response = new GetPasswordDataResponse(); int targetDepth = 2; while (context.Read()) { if (context.IsStartElement || context.IsAttribute) { if (context.TestExpression("instanceId", targetDepth)) { response.InstanceId = StringUnmarshaller.GetInstance().Unmarshall(context); continue; } if (context.TestExpression("timestamp", targetDepth)) { response.Timestamp = DateTimeUnmarshaller.GetInstance().Unmarshall(context); continue; } if (context.TestExpression("passwordData", targetDepth)) { response.PasswordData = StringUnmarshaller.GetInstance().Unmarshall(context); continue; } } } return(response); }
/// <summary> /// Loads the specified .pem file and uses it to decrypt the password data returned /// from the instance. /// </summary> /// <param name="pemFile">The full path to the .pem file to use</param> /// <param name="passwordDataResponse">Encrypted password data retrieved from the instance</param> /// <returns>The decrypted password</returns> string DecryptViaPemFile(string pemFile, GetPasswordDataResponse passwordDataResponse) { string decryptedPassword = null; try { if (!File.Exists(pemFile)) { throw new ArgumentException("Specified .pem file does not exist"); } string privateKey = null; using (var fs = File.OpenRead(pemFile)) using (var reader = new StreamReader(fs)) { privateKey = reader.ReadToEnd(); } decryptedPassword = passwordDataResponse.GetDecryptedPassword(privateKey); } catch (Exception e) { this.ThrowTerminatingError(new ErrorRecord(e, "InvalidOperationException", ErrorCategory.InvalidOperation, this)); } return(decryptedPassword); }
/// <summary> /// Retrieves the name of the keypair used on launch from the instance, then inspects /// the local AWS Toolkit store for matching account & keypair data before decrypting /// the password data. /// </summary> /// <param name="instanceId">The instance the user wants the password for</param> /// <param name="passwordDataResponse">Encrypted password data retrieved from the instance</param> /// <param name="profileLocation">The location of the ini-format credential file.</param> /// <returns>The decrypted password</returns> string DecryptViaPemDiscovery(string instanceId, GetPasswordDataResponse passwordDataResponse, string profileName, string profileLocation) { string decryptedPassword = null; try { WriteVerbose(string.Format("Retrieving keyname from running instance {0}", instanceId)); var request = new DescribeInstancesRequest(); request.InstanceIds.Add(instanceId); var response = CallAWSServiceOperation(Client, request); string keyName = response.Reservations[0].Instances[0].KeyName; WriteVerbose(string.Format("Retrieved keyname {0}, decrypting password data", keyName)); string accountSettingsKey = LookupAccountSettingsKey(this._CurrentCredentials.GetCredentials().AccessKey, profileName, profileLocation); if (string.IsNullOrEmpty(accountSettingsKey)) { throw new InvalidOperationException("Unable to determine stored account settings from access key"); } if (ToolkitKeyPairHelper.DoesPrivateKeyExist(accountSettingsKey, this._RegionEndpoint.SystemName, keyName)) { string privateKey = ToolkitKeyPairHelper.GetPrivateKey(accountSettingsKey, this._RegionEndpoint.SystemName, keyName); decryptedPassword = passwordDataResponse.GetDecryptedPassword(privateKey); } } catch (Exception e) { this.ThrowTerminatingError(new ErrorRecord(e, "InvalidOperationException", ErrorCategory.InvalidOperation, this)); } return(decryptedPassword); }
public void TestMissingLeadingZeroIssue() { string encryptedPassword = "******"; string privateKey = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAmOMJ9AIxkXBhPK+0dU0CfgqP+uMUnwPa8TwnY9+pl49s2+BGrGVIl+qccYl+\nZ0mu7MDd0MZsQBH2ZNDl+7464sqpA5PlWkl4a3/Mgc/OC00kU2o4aslLGoHUgFfIRtiA40bXEif8\nnHWQR4AWJCGS3w1oLlW4qvUwDzvLZ5dJ6n/erThZAFJa1XEPZgh3vjdLQEkxb1pkgo831niNPC5B\nZYVpr+MfBFgdVt4LdY3B7o6jkA1h7QxeZp9Au84Ag7nE3RELU7ll4U3Z9WK+8NZ+5/mJQ5LrSN47\n2KRR3Z+KBM2GYLo4U1LutL/ajUbZe1IJeTgdZMb1DMvyLu2283uiOwIDAQABAoIBAQCFzn9RjfHw\nBlk0Edtwplu+EGR/Aet0WJ1wcGNRJ9l4ClEOBzYTf/mO7AjL3bhBkd2E3C/Gn0LyuEXbanE+aPmE\nsDZIKVKcOJ0qCInmOwdsILHgR6Dk5RPUOTjQswNX7fiv8bod691M2h/SVCoMqU2v5j39/4xGI51S\nV9Tn7yMEFk5/Lmu9NNAtIrFF5ywsVbT5so6MbGqBRI8KNX71/T9KTJjXxGR9RnrKRv9zrygDw1yB\nNaJW2/HiOfbcACvehqlwBEyRRMNKZ8t+GnwnSbq30V4ojj7DlJ1piM2+11NUpIbXI1chR2iFRvyp\nP2QMp2YDlqvw5pKo8v53YYRJ5CCxAoGBAPg6lN8C39aBPJHgKgH7VtkV1QQudjHWFPRkXeixuKYi\nOZrdqrEKHt69T2aXcazqaJNNMfT3QxLtg8afe3c4Kz7TuIZI5EtKi0Ny6Wx2QhKa/Lq0YAjoAdQO\nlONf3p0eW4367fezegvZeNazKl0M4RAcW1qje5iqU42bSrPrGgq3AoGBAJ2sV/bM7g+ZRgmsbdOS\nJeoKf9n0+iA9/arhnn0/ygkYYOegQP9vOfefafLmKuImRu3mo1D7iuVhk/p7Mkkse0mQ68aZg88H\n3JBuZgf2WokN/lw0JdP40VUPobGZ9xS/a233+cRUn0Idrtslh7aIeR7yhzHIjuQYP7aAX6nnxXCd\nAoGBAOpSGoAebYBGxQ+LRPxT71rDgi8NUOOgjG1bZU6onX6uZiRrxZqTzCpFGHPm2Bb7vDX4tATj\neHygmzlfCSS0cBZBtDmHC4KLXsUP74tEYwC/L31rkhA2OqucDC5LLJCyvIhdbE/cK4SOCMTbokzu\nQHJ94jrAgobNmkvdYPpQH2gnAoGAR5MSo1BHyQD1EDMb7+zqFSILA6/3U2eQnV+qCIVKe3J7mune\nV5XwJH5TJBZj5SEnFZubC4oEdTgkapI+M4VjufN1dEP/151j/JSA8KBeXNTjYIuzmFPdAtYDupF/\n3gU/CT6GPR+E5AiBda3Fu5CcGvZRdMHsS5LOaVRBGOnDcOkCgYAA06F5y5/pdOFGrCGEoF4KOn43\nXbOG4I4WvjYP5u+CHhu4ipKvLT1TzbugO7fV8ilVU1R7R9Ur7MTCiSc7tO8QMkZbBGvUu3LAe3Hb\nAWdLBliOrgOyAjFWervBecbP9h4gn8fOALcQJqnqg2BRRhbN/lTGPsZpaLwRkS4MuQLGnw==\n-----END RSA PRIVATE KEY-----"; GetPasswordDataResponse response = new GetPasswordDataResponse { PasswordData = encryptedPassword }; string decryptedPassword = response.GetDecryptedPassword(privateKey); Assert.IsNotNull(decryptedPassword); }
/// <summary> /// Gets a particular instance's password (or at least, the original /// password assigned to the EC2 instance upon creation). /// </summary> /// <param name="amazonEC2"> /// An instance of <see cref="IAmazonEC2" />. /// </param> /// <param name="passwordEncryptionKey"> /// The AWS password encryption key, used in decryption. /// </param> /// <param name="instanceId"> /// The id of the <see cref="Instance" /> to pull back a password for. /// </param> /// <returns> /// The instance's password, as a <see cref="string" /> . /// </returns> private string GetInstancePassword( IAmazonEC2 amazonEC2, string passwordEncryptionKey, string instanceId) { string toReturn = null; this.loggingProvider.Debug( $"Requesitng encrypted password data from " + $"{nameof(Instance)} ID \"{instanceId}\"..."); GetPasswordDataRequest getPasswordDataRequest = new GetPasswordDataRequest(instanceId); GetPasswordDataResponse getPasswordDataResponse = amazonEC2.GetPasswordData(getPasswordDataRequest); this.loggingProvider.Info( $"Password data returned for {nameof(Instance)} ID " + $"\"{instanceId}\"."); try { this.loggingProvider.Debug( $"Using password encryption key to decrypt password " + $"for {nameof(Instance)} ID \"{instanceId}\"..."); toReturn = getPasswordDataResponse .GetDecryptedPassword(passwordEncryptionKey); this.loggingProvider.Info( $"Password for {nameof(Instance)} ID \"{instanceId}\" " + $"decrypted with success."); } catch (CryptographicException) { // We still want to carry on if we can't decrypt the password, // but... this.loggingProvider.Error( $"Could not decrypt password for {nameof(Instance)} " + $"ID \"{instanceId}\"! Are you sure that the password " + $"encryption key is correct? Returning null."); } return(toReturn); }
/// <summary> /// Unmarshaller the response from the service to the response class. /// </summary> /// <param name="context"></param> /// <returns></returns> public override AmazonWebServiceResponse Unmarshall(XmlUnmarshallerContext context) { GetPasswordDataResponse response = new GetPasswordDataResponse(); int originalDepth = context.CurrentDepth; int targetDepth = originalDepth + 1; if (context.IsStartOfDocument) { targetDepth = 2; } while (context.ReadAtDepth(originalDepth)) { if (context.IsStartElement || context.IsAttribute) { if (context.TestExpression("instanceId", targetDepth)) { var unmarshaller = StringUnmarshaller.Instance; response.InstanceId = unmarshaller.Unmarshall(context); continue; } if (context.TestExpression("passwordData", targetDepth)) { var unmarshaller = StringUnmarshaller.Instance; response.PasswordData = unmarshaller.Unmarshall(context); continue; } if (context.TestExpression("timestamp", targetDepth)) { var unmarshaller = DateTimeUnmarshaller.Instance; response.Timestamp = unmarshaller.Unmarshall(context); continue; } } } return(response); }
/// <summary> /// Gets a particular instance's password (or at least, the original /// password assigned to the EC2 instance upon creation). /// </summary> /// <param name="amazonEC2"> /// An instance of <see cref="IAmazonEC2" />. /// </param> /// <param name="passwordEncryptionKeys"> /// Multiple EC2 password encryption keys. /// </param> /// <param name="instanceId"> /// The id of the <see cref="Instance" /> to pull back a password for. /// </param> /// <returns> /// The instance's password, as a <see cref="string" /> . /// </returns> private string GetInstancePassword( IAmazonEC2 amazonEC2, string[] passwordEncryptionKeys, string instanceId) { string toReturn = null; this.loggingProvider.Debug( $"Requesitng encrypted password data from " + $"{nameof(Instance)} ID \"{instanceId}\"..."); GetPasswordDataRequest getPasswordDataRequest = new GetPasswordDataRequest(instanceId); GetPasswordDataResponse getPasswordDataResponse = amazonEC2.GetPasswordData(getPasswordDataRequest); this.loggingProvider.Info( $"Password data returned for {nameof(Instance)} ID " + $"\"{instanceId}\". Attempting to decrypt password with " + $"all {passwordEncryptionKeys.Length} password encryption " + $"key(s) in memory..."); // Only keep going for as long as we don't have a key decrypted. string passwordEncryptionKey = null; for (int i = 0; i < passwordEncryptionKeys.Length && string.IsNullOrEmpty(toReturn); i++) { try { passwordEncryptionKey = passwordEncryptionKeys[i]; this.loggingProvider.Debug( $"Using password encryption key " + $"{i + 1}/{passwordEncryptionKeys.Length} to " + $"decrypt password for {nameof(Instance)} ID " + $"\"{instanceId}\"..."); toReturn = getPasswordDataResponse .GetDecryptedPassword(passwordEncryptionKey); this.loggingProvider.Info( $"Password for {nameof(Instance)} ID " + $"\"{instanceId}\" decrypted with success."); } catch (CryptographicException) { // We still want to carry on if we can't decrypt the // password, but... this.loggingProvider.Warn( $"Could not decrypt password for {nameof(Instance)} " + $"ID \"{instanceId}\" using password encryption key " + $"{i + 1}/{passwordEncryptionKeys.Length}."); } } if (string.IsNullOrEmpty(toReturn)) { this.loggingProvider.Error( $"Could not decrypt password for {nameof(Instance)}: " + $"{passwordEncryptionKeys.Length} password encryption " + $"keys were tried, and none succeeded. Are you sure " + $"that the key file(s) are correct?"); } return(toReturn); }