API-style comments and ktlint formatting
Every comment is reduced to its first sentence plus @param, @return and @throws tags. Comment lines: 20040 to 8526. ktlint 1.8 applied with its default (official Kotlin) style across all modules; 262 files reformatted. The 264 remaining ktlint findings are naming and filename rules, which are code changes, and are left alone. Comments and formatting only. 1208 tests pass, counted from the XML. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
8a7f40fb13
commit
2fa430f21c
@@ -8,19 +8,11 @@ import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* The security lattice, and the two Bell–LaPadula rules it exists to enforce.
|
||||
*
|
||||
* The encoding vectors were computed independently, not read off this
|
||||
* implementation. The ten bytes are authenticated data for every construction
|
||||
* that uses a label, so an encoding that differs between platforms does not warn
|
||||
* it produces a decryption failure, or plaintext that quietly belongs to the
|
||||
* wrong sensitivity. A vector taken from the code under test would pin whatever
|
||||
* the code happens to do.
|
||||
*/
|
||||
class LabelTest {
|
||||
|
||||
private fun hex(bytes: ByteArray) = bytes.joinToString("") { "%02x".format(it) }
|
||||
|
||||
// ---- The encoding ----------------------------------------------------
|
||||
// ---- The encoding ----------------------------------------------------.
|
||||
|
||||
/** `int16be classification || uint64be compartment mask`. */
|
||||
@Test
|
||||
@@ -32,10 +24,8 @@ class LabelTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* A negative classification and a full compartment mask together, the
|
||||
* case where a sign-extension mistake or an `Int` in place of a `Long`
|
||||
* shows up. Both halves are all-ones, so a wrong shift produces something
|
||||
* that still looks plausible.
|
||||
* A negative classification and a full compartment mask together, the case
|
||||
* where a sign-extension mistake or an `Int` in place of a `Long` shows up.
|
||||
*/
|
||||
@Test
|
||||
fun `the extremes encode without sign-extension damage`() {
|
||||
@@ -43,10 +33,7 @@ class LabelTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Bit 63 is the sign bit of a Long. Building the mask with an `Int`
|
||||
* shift, or reading it back as one, loses it, and the compartment that
|
||||
* vanishes is the one nobody notices until somebody sees a file they are
|
||||
* not cleared for.
|
||||
* Bit 63 is the sign bit of a Long.
|
||||
*/
|
||||
@Test
|
||||
fun `the top compartment bit survives`() {
|
||||
@@ -66,7 +53,7 @@ class LabelTest {
|
||||
assertFailsWith<IllegalArgumentException> { Label(0, setOf(-1)) }
|
||||
}
|
||||
|
||||
// ---- Domination ------------------------------------------------------
|
||||
// ---- Domination ------------------------------------------------------.
|
||||
|
||||
@Test
|
||||
fun `a higher classification dominates a lower one`() {
|
||||
@@ -76,10 +63,7 @@ class LabelTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* The failure that reads as working. An implementation that compares
|
||||
* the classification and forgets the compartments behaves correctly on
|
||||
* every test built from levels alone, right up until somebody sees a
|
||||
* compartment they are not in.
|
||||
* The failure that reads as working.
|
||||
*/
|
||||
@Test
|
||||
fun `a higher level does NOT dominate a compartment it is not in`() {
|
||||
@@ -96,8 +80,10 @@ class LabelTest {
|
||||
val holder = Label(5, setOf(1, 2))
|
||||
assertTrue(holder.dominates(Label(5, setOf(1))))
|
||||
assertTrue(holder.dominates(Label(5, setOf(1, 2))))
|
||||
assertFalse(holder.dominates(Label(5, setOf(1, 3))),
|
||||
"an overlapping but incomplete set was treated as domination")
|
||||
assertFalse(
|
||||
holder.dominates(Label(5, setOf(1, 3))),
|
||||
"an overlapping but incomplete set was treated as domination",
|
||||
)
|
||||
}
|
||||
|
||||
/** Two labels can be incomparable, neither dominates the other. */
|
||||
@@ -115,7 +101,7 @@ class LabelTest {
|
||||
assertTrue(Label(9, setOf(3)).dominates(Label.bottom))
|
||||
}
|
||||
|
||||
// ---- Clearance: no read up -------------------------------------------
|
||||
// ---- Clearance: no read up -------------------------------------------.
|
||||
|
||||
@Test
|
||||
fun `a clearance reads what it dominates`() {
|
||||
@@ -128,15 +114,14 @@ class LabelTest {
|
||||
fun `a clearance cannot read above itself`() {
|
||||
val cleared = Clearance(maximum = Label(5))
|
||||
assertFalse(cleared.mayRead(Label(6)))
|
||||
assertFalse(cleared.mayRead(Label(5, setOf(1))),
|
||||
"a compartment outside the clearance was readable")
|
||||
assertFalse(
|
||||
cleared.mayRead(Label(5, setOf(1))),
|
||||
"a compartment outside the clearance was readable",
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum is a real bound, not decoration. A label must sit
|
||||
* INSIDE the range. Somebody cleared for sensitive work is deliberately not
|
||||
* also holding the unclassified pile, which sounds like a convenience to
|
||||
* remove until it is the reason an audit can say who could have seen what.
|
||||
* The minimum is a real bound, not decoration.
|
||||
*/
|
||||
@Test
|
||||
fun `a clearance with a floor cannot read below it`() {
|
||||
@@ -145,26 +130,11 @@ class LabelTest {
|
||||
assertFalse(cleared.mayRead(Label(1)), "a label below the floor was readable")
|
||||
}
|
||||
|
||||
// ---- Writing ---------------------------------------------------------
|
||||
// ---- Writing ---------------------------------------------------------.
|
||||
|
||||
/**
|
||||
* Writing is gated by the same range check as reading, and the
|
||||
* -property is NOT enforced, on either platform.
|
||||
*
|
||||
* Bell–LaPadula says somebody cleared to read sensitive material must not
|
||||
* write *below* their clearance, because they would carry what they read
|
||||
* down with them. iOS gates `ensureLabelKey` and `use` on
|
||||
* `clearance.permits` and nothing else, so this matches it deliberately.
|
||||
*
|
||||
* Implementing the rule on Android alone would produce a file that saves on
|
||||
* one phone and is refused on the other, with neither person able to tell
|
||||
* which rule they had met, worse than the gap itself. Filed as android#15 /
|
||||
* ios#65 so it is decided once, for both.
|
||||
*
|
||||
* This asserts the CURRENT behaviour, including the part that is a gap.
|
||||
* It should fail loudly on the day somebody implements the -property,
|
||||
* which is the point of writing the absence down rather than leaving it
|
||||
* implicit.
|
||||
* Writing is gated by the same range check as reading, and the -property is
|
||||
* NOT enforced, on either platform.
|
||||
*/
|
||||
@Test
|
||||
fun `writing uses the same range check as reading, star-property not enforced`() {
|
||||
@@ -190,7 +160,9 @@ class LabelTest {
|
||||
fun `a compartment outside the clearance cannot be written either`() {
|
||||
val cleared = Clearance(maximum = Label(5, setOf(1)))
|
||||
assertTrue(cleared.mayWrite(Label(5, setOf(1))))
|
||||
assertFalse(cleared.mayWrite(Label(5, setOf(1, 2))),
|
||||
"a compartment outside the clearance was writable")
|
||||
assertFalse(
|
||||
cleared.mayWrite(Label(5, setOf(1, 2))),
|
||||
"a compartment outside the clearance was writable",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user