Move SSD remote pin decoding to typed Kotlin

ober

c1195f1e9a01086c1b72f178edbc956d0979db3e

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 9ecd408..f906a78 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -1567,7 +1567,8 @@
                 fileExists fileIsRegular destinationNewFileDelta
                 oldDestinationBytes urlEffectivePort
                 remoteBearerTokenPresent remoteBearerTokenValid
-                remotePinPresent remoteRelativePathSafe
+                remotePinPresent remotePinOrNull remotePinSha256Length
+                remoteRelativePathSafe
                 shouldCompareMoreCompleteTruth)
         (type File)
         (type URL)
@@ -1578,6 +1579,10 @@
           (kotlin-member-get isFile))
         (extern (fileLength (file : File)) : Int
           (kotlin-member-call length))
+        (extern (bytesSize (bytes : Bytes)) : Int32
+          (kotlin-member-get size))
+        (extern (base64Decode (text : String) (flags : Int32)) : Bytes
+          (kotlin-call android util Base64 decode))
         (extern (urlPort (url : URL)) : Int32
           (kotlin-member-get port))
         (extern (urlDefaultPort (url : URL)) : Int32
@@ -1627,6 +1632,16 @@
                         (not (string-contains? token "\r"))))))
         (def (remotePinPresent (pinText : String)) : Bool
           (not (string-blank? pinText)))
+        (def (remotePinOrNull (pinText : String)
+                              (base64NoWrap : Int32)) : (Nullable Bytes)
+          (if (remotePinPresent pinText)
+              (nullable-some
+                (base64Decode
+                  (string-remove-prefix pinText "sha256/")
+                  base64NoWrap))
+              (nullable-none Bytes)))
+        (def (remotePinSha256Length (pin : Bytes)) : Bool
+          (= (bytesSize pin) (int32 32)))
         (def (remoteRelativePathSafe (relative : String)) : Bool
           (and (not (string-blank? relative))
                (and (not (string-starts-with? relative "/"))
@@ -8046,14 +8061,8 @@
        "                \"Invalid remote authentication token\""
        "            }"
        "        }"
-       "        val pin = if (remotePinPresent(pinText)) {"
-       "            val encodedPin = pinText.removePrefix(\"sha256/\")"
-       "            Base64.decode(encodedPin, Base64.NO_WRAP).also {"
-       "                require(it.size == 32) { \"SPKI SHA-256 pin must decode to 32 bytes\" }"
-       "            }"
-       "        } else {"
-       "            null"
-       "        }"
+       "        val pin = remotePinOrNull(pinText, Base64.NO_WRAP)"
+       "        if (pin != null) require(remotePinSha256Length(pin)) { \"SPKI SHA-256 pin must decode to 32 bytes\" }"
        "        require(url.protocol == \"https\" || pin == null) { \"SPKI pin requires HTTPS\" }"
        "        return RemoteConfig(url, pin, token)"
        "    }"