// SET Verifier TO 0x0000\r
short verifier = 0;\r
\r
- // FOR EACH PasswordByte IN PasswordArray IN REVERSE ORDER\r
- for (int i = arrByteChars.length-1; i >= 0; i--) {\r
- // SET Verifier TO Intermediate3 BITWISE XOR PasswordByte\r
+ if (!"".equals(password)) {\r
+ // FOR EACH PasswordByte IN PasswordArray IN REVERSE ORDER\r
+ for (int i = arrByteChars.length-1; i >= 0; i--) {\r
+ // SET Verifier TO Intermediate3 BITWISE XOR PasswordByte\r
+ verifier = rotateLeftBase15Bit(verifier);\r
+ verifier ^= arrByteChars[i];\r
+ }\r
+ \r
+ // as we haven't prepended the password length into the input array\r
+ // we need to do it now separately ...\r
verifier = rotateLeftBase15Bit(verifier);\r
- verifier ^= arrByteChars[i];\r
+ verifier ^= arrByteChars.length;\r
+ \r
+ // RETURN Verifier BITWISE XOR 0xCE4B\r
+ verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K')\r
}\r
-\r
- // as we haven't prepended the password length into the input array\r
- // we need to do it now separately ...\r
- verifier = rotateLeftBase15Bit(verifier);\r
- verifier ^= arrByteChars.length;\r
- \r
- // RETURN Verifier BITWISE XOR 0xCE4B\r
- verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K')\r
\r
return verifier & 0xFFFF;\r
}\r
cur.toFirstContentToken();\r
if (hashAlgo == null) {\r
int hash = CryptoFunctions.createXorVerifier1(password);\r
- cur.insertAttributeWithValue(getAttrName(prefix, "password"), \r
- Integer.toHexString(hash).toUpperCase(Locale.ROOT));\r
+ cur.insertAttributeWithValue(getAttrName(prefix, "password"),\r
+ String.format(Locale.ROOT, "%04X", hash).toUpperCase(Locale.ROOT));\r
} else {\r
SecureRandom random = new SecureRandom(); \r
byte salt[] = random.generateSeed(16);\r
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnsignedShortHex;
public final class TestXSSFSheet extends BaseTestXSheet {
wb.close();
}
+ @Test
+ public void protectSheet_emptyPassword() throws IOException {
+ XSSFWorkbook wb = new XSSFWorkbook();
+ XSSFSheet sheet = wb.createSheet();
+ CTSheetProtection pr = sheet.getCTWorksheet().getSheetProtection();
+ assertNull("CTSheetProtection should be null by default", pr);
+ String password = "";
+ sheet.protectSheet(password);
+ pr = sheet.getCTWorksheet().getSheetProtection();
+ assertNotNull("CTSheetProtection should be not null", pr);
+ assertTrue("sheet protection should be on", pr.isSetSheet());
+ assertTrue("object protection should be on", pr.isSetObjects());
+ assertTrue("scenario protection should be on", pr.isSetScenarios());
+ int hashVal = CryptoFunctions.createXorVerifier1(password);
+ STUnsignedShortHex xpassword = pr.xgetPassword();
+ int actualVal = Integer.parseInt(xpassword.getStringValue(),16);
+ assertEquals("well known value for top secret hash should match", hashVal, actualVal);
+
+ sheet.protectSheet(null);
+ assertNull("protectSheet(null) should unset CTSheetProtection", sheet.getCTWorksheet().getSheetProtection());
+
+ wb.close();
+ }
+
@Test
public void protectSheet_lowlevel_2013() throws IOException {
String password = "test";