/// <summary>
 /// Creates a new instance of the <see cref="PasswordProtectedPackage"/> class
 /// specifying the mandatory values.
 /// </summary>
 ///
 /// <param name="algorithm">
 /// The name of the algorithm used to protect the data.
 /// </param>
 ///
 /// <param name="salt">
 /// A string representing the encoding of the bytes that were used as
 /// the salt when protecting the data.
 /// </param>
 ///
 /// <param name="keyLength">
 /// The number of bits used by the algorithm.
 /// </param>
 ///
 /// <remarks>
 /// In general, the salt is a series of bytes encoded in an
 /// application-dependent way. The length of the salt must match the
 /// algorithm. It is recommended that the salt encoding be base64.
 /// </remarks>
 /// <exception cref="ArgumentException">
 /// The <paramref name="salt"/> parameter is <b>null</b> or empty.
 /// </exception>
 ///
 /// <exception cref="ArgumentOutOfRangeException">
 /// The <paramref name="keyLength"/> parameter is negative or zero.
 /// </exception>
 ///
 public PasswordProtectedPackage(
     PasswordProtectAlgorithm algorithm,
     string salt,
     int keyLength)
     : base(TypeId)
 {
     PasswordProtectAlgorithm = algorithm;
     Salt      = salt;
     KeyLength = keyLength;
 }
        /// <summary>
        /// Populates this PasswordProtectedPackage instance from the data 
        /// in the XML.
        /// </summary>
        /// 
        /// <param name="typeSpecificXml">
        /// The XML to get the file data from.
        /// </param>
        /// 
        /// <exception cref="InvalidOperationException">
        /// The first node in the <paramref name="typeSpecificXml"/> 
        /// parameter is not a file node.
        /// </exception>
        /// 
        protected override void ParseXml(IXPathNavigable typeSpecificXml)
        {
            XPathNavigator packageNav =
                typeSpecificXml.CreateNavigator().SelectSingleNode(
                    "password-protected-package/encrypt-algorithm");

            Validator.ThrowInvalidIfNull(packageNav, "PackageUnexpectedNode");

            _algorithmName =
                packageNav.SelectSingleNode("algorithm-name").Value;

            switch (_algorithmName)
            {
                case "none":
                    _algorithm = PasswordProtectAlgorithm.None;
                    break;

                case "hmac-sha1-3des":
                    _algorithm = PasswordProtectAlgorithm.HmacSha13Des;
                    break;

                case "hmac-sha256-aes256":
                    _algorithm = PasswordProtectAlgorithm.HmacSha256Aes256;
                    break;

                default:
                    _algorithm = PasswordProtectAlgorithm.Unknown;
                    break;
            }

            _salt = packageNav.SelectSingleNode("parameters/salt").Value;
            _hashIterations =
                packageNav.SelectSingleNode(
                    "parameters/iteration-count").ValueAsInt;

            _keyLength =
                packageNav.SelectSingleNode(
                    "parameters/key-length").ValueAsInt;
        }
 /// <summary>
 /// Creates a new instance of the <see cref="PasswordProtectedPackage"/> class 
 /// specifying the mandatory values.
 /// </summary>
 /// 
 /// <param name="algorithm">
 /// The name of the algorithm used to protect the data.
 /// </param>
 /// 
 /// <param name="salt">
 /// A string representing the encoding of the bytes that were used as
 /// the salt when protecting the data.
 /// </param>
 /// 
 /// <param name="keyLength">
 /// The number of bits used by the algorithm.
 /// </param>
 /// 
 /// <remarks>
 /// In general, the salt is a series of bytes encoded in an 
 /// application-dependent way. The length of the salt must match the 
 /// algorithm. It is recommended that the salt encoding be base64.
 /// </remarks>
 /// <exception cref="ArgumentException">
 /// The <paramref name="salt"/> parameter is <b>null</b> or empty.
 /// </exception>
 /// 
 /// <exception cref="ArgumentOutOfRangeException">
 /// The <paramref name="keyLength"/> parameter is negative or zero.
 /// </exception>
 /// 
 public PasswordProtectedPackage(
     PasswordProtectAlgorithm algorithm, 
     string salt, 
     int keyLength)
     : base(TypeId)
 {
     this.PasswordProtectAlgorithm = algorithm;
     this.Salt = salt;
     this.KeyLength = keyLength;
 }
        internal ConnectPackageCreationParameters(
            OfflineWebApplicationConnection connection,
            String identityCode, 
            String friendlyName, 
            String securityQuestion, 
            String securityAnswer, 
            String applicationPatientId, 
            Boolean isSecurityAnswerAvailable,
            Boolean isIdentityCodeRequired)
        {
            Validator.ThrowIfArgumentNull(connection, "connection", "ConnectPackageConnectionNull");

            Validator.ThrowArgumentExceptionIf(
                isIdentityCodeRequired && String.IsNullOrEmpty(identityCode),
                "identityCode",
                "PackageCreateHRIMissingMandatory");

            Validator.ThrowIfStringNullOrEmpty(friendlyName, "friendlyName");
            Validator.ThrowIfStringNullOrEmpty(securityQuestion, "friendlyName");

            if (isSecurityAnswerAvailable)
            {
                Validator.ThrowIfStringNullOrEmpty(securityAnswer, "securityAnswer");
                Validator.ThrowArgumentOutOfRangeIf(
                    securityAnswer.Length < 6,
                    "securityAnswer",
                    "PackageCreateHRIAnswerLength");
            }

            Validator.ThrowIfStringNullOrEmpty(applicationPatientId, "applicationPatientId");

            _connection = connection;
            _identityCode = identityCode;
            _friendlyName = friendlyName;
            _securityQuestion = securityQuestion;
            _securityAnswer = securityAnswer;
            _applicationPatientId = applicationPatientId;
            _salt = Guid.NewGuid().ToString();
            _passwordProtectAlgorithm = PasswordProtectAlgorithm.HmacSha256Aes256;
            _connectPackageEncryptionAlgorithmName = "AES256";
            _blobChunkEncryptionAlgorithmName = "AES256";

            _encryptionParameterGenerationIterationCount = 20000;
            if (isSecurityAnswerAvailable)
            {
                SetupEncryptionParameters();
            }
            _id = Guid.NewGuid();
        }