public bool ReadKey(PdfDictionary enc, byte[] password)
{
if (password == null)
password = new byte[0];
byte[] oValue = DocWriter.GetISOBytes(enc.Get(PdfName.O).ToString());
byte[] uValue = DocWriter.GetISOBytes(enc.Get(PdfName.U).ToString());
byte[] oeValue = DocWriter.GetISOBytes(enc.Get(PdfName.OE).ToString());
byte[] ueValue = DocWriter.GetISOBytes(enc.Get(PdfName.UE).ToString());
byte[] perms = DocWriter.GetISOBytes(enc.Get(PdfName.PERMS).ToString());
bool isUserPass = false;
IDigest md = DigestUtilities.GetDigest("SHA-256");
md.BlockUpdate(password, 0, Math.Min(password.Length, 127));
md.BlockUpdate(oValue, VALIDATION_SALT_OFFSET, SALT_LENGHT);
md.BlockUpdate(uValue, 0, OU_LENGHT);
byte[] hash = DigestUtilities.DoFinal(md);
bool isOwnerPass = CompareArray(hash, oValue, 32);
AESCipherCBCnoPad ac;
if (isOwnerPass) {
md.BlockUpdate(password, 0, Math.Min(password.Length, 127));
md.BlockUpdate(oValue, KEY_SALT_OFFSET, SALT_LENGHT);
md.BlockUpdate(uValue, 0, OU_LENGHT);
md.DoFinal(hash, 0);
ac = new AESCipherCBCnoPad(false, hash);
key = ac.ProcessBlock(oeValue, 0, oeValue.Length);
}
else {
md.BlockUpdate(password, 0, Math.Min(password.Length, 127));
md.BlockUpdate(uValue, VALIDATION_SALT_OFFSET, SALT_LENGHT);
md.DoFinal(hash, 0);
isUserPass = CompareArray(hash, uValue, 32);
if (!isUserPass)
throw new BadPasswordException(MessageLocalization.GetComposedMessage("bad.user.password"));
md.BlockUpdate(password, 0, Math.Min(password.Length, 127));
md.BlockUpdate(uValue, KEY_SALT_OFFSET, SALT_LENGHT);
md.DoFinal(hash, 0);
ac = new AESCipherCBCnoPad(false, hash);
key = ac.ProcessBlock(ueValue, 0, ueValue.Length);
}
ac = new AESCipherCBCnoPad(false, key);
byte[] decPerms = ac.ProcessBlock(perms, 0, perms.Length);
if (decPerms[9] != (byte)'a' || decPerms[10] != (byte)'d' || decPerms[11] != (byte)'b')
throw new BadPasswordException(MessageLocalization.GetComposedMessage("bad.user.password"));
permissions = (decPerms[0] & 0xff) | ((decPerms[1] & 0xff) << 8)
| ((decPerms[2] & 0xff) << 16) | ((decPerms[2] & 0xff) << 24);
encryptMetadata = decPerms[8] == (byte)'T';
return isOwnerPass;
}