public void SetupAllKeys(byte[] userPassword, byte[] ownerPassword, int permissions)
{
if (ownerPassword == null || ownerPassword.Length == 0)
ownerPassword = DigestAlgorithms.Digest("MD5", CreateDocumentId());
md5.Reset();
permissions |= (int)((revision == STANDARD_ENCRYPTION_128 || revision == AES_128 || revision == AES_256) ? (uint)0xfffff0c0 : (uint)0xffffffc0);
permissions &= unchecked((int)0xfffffffc);
this.permissions = permissions;
if (revision == AES_256) {
if (userPassword == null)
userPassword = new byte[0];
documentID = CreateDocumentId();
byte[] uvs = IVGenerator.GetIV(8);
byte[] uks = IVGenerator.GetIV(8);
key = IVGenerator.GetIV(32);
// Algorithm 3.8.1
IDigest md = DigestUtilities.GetDigest("SHA-256");
md.BlockUpdate(userPassword, 0, Math.Min(userPassword.Length, 127));
md.BlockUpdate(uvs, 0, uvs.Length);
userKey = new byte[48];
md.DoFinal(userKey, 0);
System.Array.Copy(uvs, 0, userKey, 32, 8);
System.Array.Copy(uks, 0, userKey, 40, 8);
// Algorithm 3.8.2
md.BlockUpdate(userPassword, 0, Math.Min(userPassword.Length, 127));
md.BlockUpdate(uks, 0, uks.Length);
byte[] tempDigest = new byte[32];
md.DoFinal(tempDigest, 0);
AESCipherCBCnoPad ac = new AESCipherCBCnoPad(true, tempDigest);
ueKey = ac.ProcessBlock(key, 0, key.Length);
// Algorithm 3.9.1
byte[] ovs = IVGenerator.GetIV(8);
byte[] oks = IVGenerator.GetIV(8);
md.BlockUpdate(ownerPassword, 0, Math.Min(ownerPassword.Length, 127));
md.BlockUpdate(ovs, 0, ovs.Length);
md.BlockUpdate(userKey, 0, userKey.Length);
ownerKey = new byte[48];
md.DoFinal(ownerKey, 0);
System.Array.Copy(ovs, 0, ownerKey, 32, 8);
System.Array.Copy(oks, 0, ownerKey, 40, 8);
// Algorithm 3.9.2
md.BlockUpdate(ownerPassword, 0, Math.Min(ownerPassword.Length, 127));
md.BlockUpdate(oks, 0, oks.Length);
md.BlockUpdate(userKey, 0, userKey.Length);
md.DoFinal(tempDigest, 0);
ac = new AESCipherCBCnoPad(true, tempDigest);
oeKey = ac.ProcessBlock(key, 0, key.Length);
// Algorithm 3.10
byte[] permsp = IVGenerator.GetIV(16);
permsp[0] = (byte)permissions;
permsp[1] = (byte)(permissions >> 8);
permsp[2] = (byte)(permissions >> 16);
permsp[3] = (byte)(permissions >> 24);
permsp[4] = (byte)(255);
permsp[5] = (byte)(255);
permsp[6] = (byte)(255);
permsp[7] = (byte)(255);
permsp[8] = encryptMetadata ? (byte)'T' : (byte)'F';
permsp[9] = (byte)'a';
permsp[10] = (byte)'d';
permsp[11] = (byte)'b';
ac = new AESCipherCBCnoPad(true, key);
perms = ac.ProcessBlock(permsp, 0, permsp.Length);
}
else {
//PDF refrence 3.5.2 Standard Security Handler, Algorithum 3.3-1
//If there is no owner password, use the user password instead.
byte[] userPad = PadPassword(userPassword);
byte[] ownerPad = PadPassword(ownerPassword);
this.ownerKey = ComputeOwnerKey(userPad, ownerPad);
documentID = CreateDocumentId();
SetupByUserPad(this.documentID, userPad, this.ownerKey, permissions);
}
}