Beispiel #1
0
        /**
         * instead of a password, it's also possible to decrypt via certificate.
         * Warning: this code is experimental and hasn't been validated
         *
         * @see <a href="http://social.msdn.microsoft.com/Forums/en-US/cc9092bb-0c82-4b5b-ae21-abf643bdb37c/agile-encryption-with-certificates">Agile encryption with certificates</a>
         *
         * @param keyPair
         * @param x509
         * @return true, when the data can be successfully decrypted with the given private key
         * @throws GeneralSecurityException
         */
        public bool VerifyPassword(KeyPair keyPair, X509Certificate x509)
        {
            AgileEncryptionVerifier ver        = (AgileEncryptionVerifier)builder.GetVerifier();
            AgileEncryptionHeader   header     = (AgileEncryptionHeader)builder.GetHeader();
            HashAlgorithm           hashAlgo   = header.HashAlgorithm;
            CipherAlgorithm         cipherAlgo = header.CipherAlgorithm;
            int blockSize = header.BlockSize;

            AgileCertificateEntry ace = null;

            foreach (AgileCertificateEntry aceEntry in ver.GetCertificates())
            {
                if (x509.Equals(aceEntry.x509))
                {
                    ace = aceEntry;
                    break;
                }
            }
            if (ace == null)
            {
                return(false);
            }

            Cipher cipher = Cipher.GetInstance("RSA");

            cipher.Init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
            byte[]        keyspec   = cipher.DoFinal(ace.encryptedKey);
            SecretKeySpec secretKey = new SecretKeySpec(keyspec, ver.CipherAlgorithm.jceId);

            Mac x509Hmac = CryptoFunctions.GetMac(hashAlgo);

            x509Hmac.Init(secretKey);
            byte[] certVerifier = x509Hmac.DoFinal(ace.x509.GetEncoded());

            byte[] vec = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, kIntegrityKeyBlock, blockSize);
            cipher = GetCipher(secretKey, cipherAlgo, ver.ChainingMode, vec, Cipher.DECRYPT_MODE);
            byte[] hmacKey = cipher.DoFinal(header.GetEncryptedHmacKey());
            hmacKey = GetBlock0(hmacKey, hashAlgo.hashSize);

            vec    = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, kIntegrityValueBlock, blockSize);
            cipher = GetCipher(secretKey, cipherAlgo, ver.ChainingMode, vec, Cipher.DECRYPT_MODE);
            byte[] hmacValue = cipher.DoFinal(header.GetEncryptedHmacValue());
            hmacValue = GetBlock0(hmacValue, hashAlgo.hashSize);


            if (Arrays.Equals(ace.certVerifier, certVerifier))
            {
                SetSecretKey(secretKey);
                SetIntegrityHmacKey(hmacKey);
                SetIntegrityHmacValue(hmacValue);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #2
0
        public void Initialize(EncryptionInfo info, ILittleEndianInput dis)
        {
            this.info = info;

            EncryptionDocument ed = ParseDescriptor((DocumentInputStream)dis);

            header   = new AgileEncryptionHeader(ed);
            verifier = new AgileEncryptionVerifier(ed);
            if (info.VersionMajor == EncryptionMode.Agile.VersionMajor &&
                info.VersionMinor == EncryptionMode.Agile.VersionMinor)
            {
                decryptor = new AgileDecryptor(this);
                encryptor = new AgileEncryptor(this);
            }
        }
Beispiel #3
0
        public void Initialize(EncryptionInfo info, CipherAlgorithm cipherAlgorithm, HashAlgorithm hashAlgorithm, int keyBits, int blockSize, ChainingMode chainingMode)
        {
            this.info = info;

            if (cipherAlgorithm == null)
            {
                cipherAlgorithm = CipherAlgorithm.aes128;
            }
            if (cipherAlgorithm == CipherAlgorithm.rc4)
            {
                throw new EncryptedDocumentException("RC4 must not be used with agile encryption.");
            }
            if (hashAlgorithm == null)
            {
                hashAlgorithm = HashAlgorithm.sha1;
            }
            if (chainingMode == null)
            {
                chainingMode = ChainingMode.cbc;
            }
            if (!(chainingMode == ChainingMode.cbc || chainingMode == ChainingMode.cfb))
            {
                throw new EncryptedDocumentException("Agile encryption only supports CBC/CFB chaining.");
            }
            if (keyBits == -1)
            {
                keyBits = cipherAlgorithm.defaultKeySize;
            }
            if (blockSize == -1)
            {
                blockSize = cipherAlgorithm.blockSize;
            }
            bool found = false;

            foreach (int ks in cipherAlgorithm.allowedKeySize)
            {
                found |= (ks == keyBits);
            }
            if (!found)
            {
                throw new EncryptedDocumentException("KeySize " + keyBits + " not allowed for Cipher " + cipherAlgorithm.ToString());
            }
            header    = new AgileEncryptionHeader(cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode);
            verifier  = new AgileEncryptionVerifier(cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode);
            decryptor = new AgileDecryptor(this);
            encryptor = new AgileEncryptor(this);
        }
Beispiel #4
0
        /**
         * Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message),
         * which the DataIntegrity element will verify by using the Salt generated in step 2 as the key.
         * Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be
         * used as the message.
         *
         * Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes:
         * 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33.
         **/
        protected void UpdateIntegrityHMAC(FileInfo tmpFile, int oleStreamSize)
        {
            // as the integrity hmac needs to contain the StreamSize,
            // it's not possible to calculate it on-the-fly while buffering
            // TODO: add stream size parameter to GetDataStream()
            AgileEncryptionVerifier ver      = builder.GetVerifier();
            HashAlgorithm           hashAlgo = ver.HashAlgorithm;
            Mac integrityMD = CryptoFunctions.GetMac(hashAlgo);

            integrityMD.Init(new SecretKeySpec(integritySalt, hashAlgo.jceHmacId));

            byte[] buf = new byte[1024];
            LittleEndian.PutLong(buf, 0, oleStreamSize);
            integrityMD.Update(buf, 0, LittleEndian.LONG_SIZE);

            FileStream fis = tmpFile.Create();

            try {
                int readBytes;
                while ((readBytes = fis.Read(buf, 0, buf.Length)) > 0)
                {
                    integrityMD.Update(buf, 0, readBytes);
                }
            } finally {
                fis.Close();
            }

            byte[] hmacValue = integrityMD.DoFinal();

            AgileEncryptionHeader header = builder.GetHeader();
            int blockSize = header.BlockSize;

            byte[] iv     = CryptoFunctions.GenerateIv(header.HashAlgorithm, header.KeySalt, AgileDecryptor.kIntegrityValueBlock, blockSize);
            Cipher cipher = CryptoFunctions.GetCipher(GetSecretKey(), header.CipherAlgorithm, header.ChainingMode, iv, Cipher.ENCRYPT_MODE);

            byte[] hmacValueFilled    = GetBlock0(hmacValue, AgileDecryptor.GetNextBlockSize(hmacValue.Length, blockSize));
            byte[] encryptedHmacValue = cipher.DoFinal(hmacValueFilled);

            header.SetEncryptedHmacValue(encryptedHmacValue);
        }
Beispiel #5
0
        /**
         * Set decryption password
         */
        public override bool VerifyPassword(String password)
        {
            AgileEncryptionVerifier ver        = (AgileEncryptionVerifier)builder.GetVerifier();
            AgileEncryptionHeader   header     = (AgileEncryptionHeader)builder.GetHeader();
            HashAlgorithm           hashAlgo   = header.HashAlgorithm;
            CipherAlgorithm         cipherAlgo = header.CipherAlgorithm;
            int blockSize = header.BlockSize;
            int keySize   = header.KeySize / 8;

            byte[] pwHash = CryptoFunctions.HashPassword(password, ver.HashAlgorithm, ver.Salt, ver.SpinCount);

            /**
             * encryptedVerifierHashInput: This attribute MUST be generated by using the following steps:
             * 1. Generate a random array of bytes with the number of bytes used specified by the saltSize
             *    attribute.
             * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password,
             *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
             *    consisting of the following bytes: 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, and 0x79.
             * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue
             *    attribute as an Initialization vector as specified in section 2.3.4.12. If the array of bytes is not an
             *    integral multiple of blockSize bytes, pad the array with 0x00 to the next integral multiple of
             *    blockSize bytes.
             * 4. Use base64 to encode the result of step 3.
             */
            byte[] verfierInputEnc = hashInput(builder, pwHash, kVerifierInputBlock, ver.EncryptedVerifier, Cipher.DECRYPT_MODE);
            SetVerifier(verfierInputEnc);
            MessageDigest hashMD = CryptoFunctions.GetMessageDigest(hashAlgo);

            byte[] verifierHash = hashMD.Digest(verfierInputEnc);

            /**
             * encryptedVerifierHashValue: This attribute MUST be generated by using the following steps:
             * 1. Obtain the hash value of the random array of bytes generated in step 1 of the steps for
             *    encryptedVerifierHashInput.
             * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password,
             *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
             *    consisting of the following bytes: 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, and 0x4e.
             * 3. Encrypt the hash value obtained in step 1 by using the binary form of the saltValue attribute as
             *    an Initialization vector as specified in section 2.3.4.12. If hashSize is not an integral multiple of
             *    blockSize bytes, pad the hash value with 0x00 to an integral multiple of blockSize bytes.
             * 4. Use base64 to encode the result of step 3.
             */
            byte[] verifierHashDec = hashInput(builder, pwHash, kHashedVerifierBlock, ver.EncryptedVerifierHash, Cipher.DECRYPT_MODE);
            verifierHashDec = CryptoFunctions.GetBlock0(verifierHashDec, hashAlgo.hashSize);

            /**
             * encryptedKeyValue: This attribute MUST be generated by using the following steps:
             * 1. Generate a random array of bytes that is the same size as specified by the
             *    Encryptor.KeyData.keyBits attribute of the parent element.
             * 2. Generate an encryption key as specified in section 2.3.4.11, using the user-supplied password,
             *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
             *    consisting of the following bytes: 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, and 0xd6.
             * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue
             *    attribute as an Initialization vector as specified in section 2.3.4.12. If the array of bytes is not an
             *    integral multiple of blockSize bytes, pad the array with 0x00 to an integral multiple of
             *    blockSize bytes.
             * 4. Use base64 to encode the result of step 3.
             */
            byte[] keyspec = hashInput(builder, pwHash, kCryptoKeyBlock, ver.EncryptedKey, Cipher.DECRYPT_MODE);
            keyspec = CryptoFunctions.GetBlock0(keyspec, keySize);
            SecretKeySpec secretKey = new SecretKeySpec(keyspec, ver.CipherAlgorithm.jceId);

            /**
             * 1. Obtain the intermediate key by decrypting the encryptedKeyValue from a KeyEncryptor
             *    Contained within the KeyEncryptors sequence. Use this key for encryption operations in the
             *    remaining steps of this section.
             * 2. Generate a random array of bytes, known as Salt, of the same length as the value of the
             *    KeyData.HashSize attribute.
             * 3. Encrypt the random array of bytes generated in step 2 by using the binary form of the
             *    KeyData.saltValue attribute and a blockKey byte array consisting of the following bytes: 0x5f,
             *    0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, and 0xf6 used to form an Initialization vector as specified in
             *    section 2.3.4.12. If the array of bytes is not an integral multiple of blockSize bytes, pad the
             *    array with 0x00 to the next integral multiple of blockSize bytes.
             * 4. Assign the encryptedHmacKey attribute to the base64-encoded form of the result of step 3.
             */
            byte[] vec    = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, kIntegrityKeyBlock, blockSize);
            Cipher cipher = CryptoFunctions.GetCipher(secretKey, cipherAlgo, ver.ChainingMode, vec, Cipher.DECRYPT_MODE);

            byte[] hmacKey = cipher.DoFinal(header.GetEncryptedHmacKey());
            hmacKey = CryptoFunctions.GetBlock0(hmacKey, hashAlgo.hashSize);

            /**
             * 5. Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message),
             *    which the DataIntegrity element will verify by using the Salt generated in step 2 as the key.
             *    Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be
             *    used as the message.
             * 6. Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes:
             *    0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33.
             * 7. Assign the encryptedHmacValue attribute to the base64-encoded form of the result of step 6.
             */
            vec    = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, kIntegrityValueBlock, blockSize);
            cipher = CryptoFunctions.GetCipher(secretKey, cipherAlgo, ver.ChainingMode, vec, Cipher.DECRYPT_MODE);
            byte[] hmacValue = cipher.DoFinal(header.GetEncryptedHmacValue());
            hmacValue = CryptoFunctions.GetBlock0(hmacValue, hashAlgo.hashSize);

            if (Arrays.Equals(verifierHashDec, verifierHash))
            {
                SetSecretKey(secretKey);
                SetIntegrityHmacKey(hmacKey);
                SetIntegrityHmacValue(hmacValue);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #6
0
        public override void ConfirmPassword(String password, byte[] keySpec, byte[] keySalt, byte[] verifier, byte[] verifierSalt, byte[] integritySalt)
        {
            AgileEncryptionVerifier ver = builder.GetVerifier();

            ver.Salt = (/*setter*/ verifierSalt);
            AgileEncryptionHeader header = builder.GetHeader();

            header.KeySalt = (/*setter*/ keySalt);
            HashAlgorithm hashAlgo = ver.HashAlgorithm;

            int blockSize = header.BlockSize;

            pwHash = HashPassword(password, hashAlgo, verifierSalt, ver.SpinCount);

            /**
             * encryptedVerifierHashInput: This attribute MUST be generated by using the following steps:
             * 1. Generate a random array of bytes with the number of bytes used specified by the saltSize
             *    attribute.
             * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password,
             *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
             *    consisting of the following bytes: 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, and 0x79.
             * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue
             *    attribute as an Initialization vector as specified in section 2.3.4.12. If the array of bytes is not an
             *    integral multiple of blockSize bytes, pad the array with 0x00 to the next integral multiple of
             *    blockSize bytes.
             * 4. Use base64 to encode the result of step 3.
             */
            byte[] encryptedVerifier = AgileDecryptor.hashInput(builder, pwHash, AgileDecryptor.kVerifierInputBlock, verifier, Cipher.ENCRYPT_MODE);
            ver.EncryptedVerifier = (/*setter*/ encryptedVerifier);


            /**
             * encryptedVerifierHashValue: This attribute MUST be generated by using the following steps:
             * 1. Obtain the hash value of the random array of bytes generated in step 1 of the steps for
             *    encryptedVerifierHashInput.
             * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password,
             *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
             *    consisting of the following bytes: 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, and 0x4e.
             * 3. Encrypt the hash value obtained in step 1 by using the binary form of the saltValue attribute as
             *    an Initialization vector as specified in section 2.3.4.12. If hashSize is not an integral multiple of
             *    blockSize bytes, pad the hash value with 0x00 to an integral multiple of blockSize bytes.
             * 4. Use base64 to encode the result of step 3.
             */
            MessageDigest hashMD = GetMessageDigest(hashAlgo);

            byte[] hashedVerifier        = hashMD.Digest(verifier);
            byte[] encryptedVerifierHash = AgileDecryptor.hashInput(builder, pwHash, AgileDecryptor.kHashedVerifierBlock, hashedVerifier, Cipher.ENCRYPT_MODE);
            ver.EncryptedVerifierHash = (/*setter*/ encryptedVerifierHash);

            /**
             * encryptedKeyValue: This attribute MUST be generated by using the following steps:
             * 1. Generate a random array of bytes that is the same size as specified by the
             *    Encryptor.KeyData.keyBits attribute of the parent element.
             * 2. Generate an encryption key as specified in section 2.3.4.11, using the user-supplied password,
             *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
             *    consisting of the following bytes: 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, and 0xd6.
             * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue
             *    attribute as an Initialization vector as specified in section 2.3.4.12. If the array of bytes is not an
             *    integral multiple of blockSize bytes, pad the array with 0x00 to an integral multiple of
             *    blockSize bytes.
             * 4. Use base64 to encode the result of step 3.
             */
            byte[] encryptedKey = AgileDecryptor.hashInput(builder, pwHash, AgileDecryptor.kCryptoKeyBlock, keySpec, Cipher.ENCRYPT_MODE);
            ver.EncryptedKey = (/*setter*/ encryptedKey);

            ISecretKey secretKey = new SecretKeySpec(keySpec, ver.CipherAlgorithm.jceId);

            SetSecretKey(secretKey);

            /*
             * 2.3.4.14 DataIntegrity Generation (Agile Encryption)
             *
             * The DataIntegrity element Contained within an Encryption element MUST be generated by using
             * the following steps:
             * 1. Obtain the intermediate key by decrypting the encryptedKeyValue from a KeyEncryptor
             *    Contained within the KeyEncryptors sequence. Use this key for encryption operations in the
             *    remaining steps of this section.
             * 2. Generate a random array of bytes, known as Salt, of the same length as the value of the
             *    KeyData.HashSize attribute.
             * 3. Encrypt the random array of bytes generated in step 2 by using the binary form of the
             *    KeyData.saltValue attribute and a blockKey byte array consisting of the following bytes:
             *    0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, and 0xf6 used to form an Initialization vector as
             *    specified in section 2.3.4.12. If the array of bytes is not an integral multiple of blockSize
             *    bytes, pad the array with 0x00 to the next integral multiple of blockSize bytes.
             * 4. Assign the encryptedHmacKey attribute to the base64-encoded form of the result of step 3.
             * 5. Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message),
             *    which the DataIntegrity element will verify by using the Salt generated in step 2 as the key.
             *    Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be
             *    used as the message.
             * 6. Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes:
             *    0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33.
             * 7.  Assign the encryptedHmacValue attribute to the base64-encoded form of the result of step 6.
             */
            this.integritySalt = integritySalt;

            try {
                byte[] vec              = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, AgileDecryptor.kIntegrityKeyBlock, header.BlockSize);
                Cipher cipher           = GetCipher(secretKey, ver.CipherAlgorithm, ver.ChainingMode, vec, Cipher.ENCRYPT_MODE);
                byte[] FilledSalt       = GetBlock0(integritySalt, AgileDecryptor.GetNextBlockSize(integritySalt.Length, blockSize));
                byte[] encryptedHmacKey = cipher.DoFinal(FilledSalt);
                header.SetEncryptedHmacKey(encryptedHmacKey);

                cipher = Cipher.GetInstance("RSA");
                foreach (AgileCertificateEntry ace in ver.GetCertificates())
                {
                    cipher.Init(Cipher.ENCRYPT_MODE, ace.x509.GetPublicKey());
                    ace.encryptedKey = cipher.DoFinal(GetSecretKey().GetEncoded());
                    Mac x509Hmac = CryptoFunctions.GetMac(hashAlgo);
                    x509Hmac.Init(GetSecretKey());
                    ace.certVerifier = x509Hmac.DoFinal(ace.x509.GetEncoded());
                }
            } catch (Exception e) {
                throw new EncryptedDocumentException(e);
            }
        }
Beispiel #7
0
        protected EncryptionDocument CreateEncryptionDocument()
        {
            AgileEncryptionVerifier ver    = builder.GetVerifier();
            AgileEncryptionHeader   header = builder.GetHeader();

            EncryptionDocument ed     = EncryptionDocument.NewInstance();
            CT_Encryption      edRoot = ed.AddNewEncryption();

            CT_KeyData       keyData    = edRoot.AddNewKeyData();
            CT_KeyEncryptors keyEncList = edRoot.AddNewKeyEncryptors();
            CT_KeyEncryptor  keyEnc     = keyEncList.AddNewKeyEncryptor();

            keyEnc.uri = (/*setter*/ passwordUri);
            CT_PasswordKeyEncryptor keyPass = keyEnc.AddNewEncryptedPasswordKey();

            keyPass.spinCount = (uint)ver.SpinCount;

            keyData.saltSize = (uint)header.BlockSize;
            keyPass.saltSize = (uint)header.BlockSize;

            keyData.blockSize = (uint)header.BlockSize;
            keyPass.blockSize = (uint)header.BlockSize;

            keyData.keyBits = (uint)header.KeySize;
            keyPass.keyBits = (uint)header.KeySize;

            HashAlgorithm hashAlgo = header.HashAlgorithm;

            keyData.hashSize = (uint)hashAlgo.hashSize;
            keyPass.hashSize = (uint)hashAlgo.hashSize;

            ST_CipherAlgorithm?xmlCipherAlgo = (ST_CipherAlgorithm?)Enum.Parse(typeof(ST_CipherAlgorithm), header.CipherAlgorithm.xmlId);

            if (xmlCipherAlgo == null)
            {
                throw new EncryptedDocumentException("CipherAlgorithm " + header.CipherAlgorithm + " not supported.");
            }
            keyData.cipherAlgorithm = (/*setter*/ xmlCipherAlgo.Value);
            keyPass.cipherAlgorithm = (/*setter*/ xmlCipherAlgo.Value);

            switch (header.ChainingMode.jceId)
            {
            case "cbc":
                keyData.cipherChaining = (/*setter*/ ST_CipherChaining.ChainingModeCBC);
                keyPass.cipherChaining = (/*setter*/ ST_CipherChaining.ChainingModeCBC);
                break;

            case "cfb":
                keyData.cipherChaining = (/*setter*/ ST_CipherChaining.ChainingModeCFB);
                keyPass.cipherChaining = (/*setter*/ ST_CipherChaining.ChainingModeCFB);
                break;

            default:
                throw new EncryptedDocumentException("ChainingMode " + header.ChainingMode + " not supported.");
            }

            ST_HashAlgorithm?xmlHashAlgo = (ST_HashAlgorithm?)Enum.Parse(typeof(ST_HashAlgorithm), hashAlgo.ecmaString);

            if (xmlHashAlgo == null)
            {
                throw new EncryptedDocumentException("HashAlgorithm " + hashAlgo + " not supported.");
            }
            keyData.hashAlgorithm = (/*setter*/ xmlHashAlgo.Value);
            keyPass.hashAlgorithm = (/*setter*/ xmlHashAlgo.Value);

            keyData.saltValue = (/*setter*/ header.KeySalt);
            keyPass.saltValue = (/*setter*/ ver.Salt);
            keyPass.encryptedVerifierHashInput = (/*setter*/ ver.EncryptedVerifier);
            keyPass.encryptedVerifierHashValue = (/*setter*/ ver.EncryptedVerifierHash);
            keyPass.encryptedKeyValue          = (/*setter*/ ver.EncryptedKey);

            CT_DataIntegrity hmacData = edRoot.AddNewDataIntegrity();

            hmacData.encryptedHmacKey   = (/*setter*/ header.GetEncryptedHmacKey());
            hmacData.encryptedHmacValue = (/*setter*/ header.GetEncryptedHmacValue());

            foreach (AgileCertificateEntry ace in ver.GetCertificates())
            {
                keyEnc     = keyEncList.AddNewKeyEncryptor();
                keyEnc.uri = (/*setter*/ certificateUri);
                CT_CertificateKeyEncryptor certData = keyEnc.AddNewEncryptedCertificateKey();
                try {
                    certData.X509Certificate = ace.x509.GetEncoded();
                } catch (Exception e) {
                    throw new EncryptedDocumentException(e);
                }
                certData.encryptedKeyValue = (/*setter*/ ace.encryptedKey);
                certData.certVerifier      = (/*setter*/ ace.certVerifier);
            }

            return(ed);
        }