@@ -19,8 +19,8 @@ import kotlin.contracts.InvocationKind
1919import kotlin.contracts.contract
2020
2121sealed interface Purpose {
22- class Public (val keyProvider : () -> KeyPair ) : Purpose
23- class Local (val keyProvider : () -> SymmetricKey ) : Purpose
22+ class Public (val keyProvider : (footer: TaintedFooter ) -> KeyPair ) : Purpose
23+ class Local (val keyProvider : (footer: TaintedFooter ) -> SymmetricKey ) : Purpose
2424}
2525
2626@PasetoDslMarker
@@ -81,23 +81,23 @@ inline fun tokenService(version: Version, purpose: Purpose, init: TokenServiceBu
8181
8282sealed interface TokenService {
8383 fun encode (token : Token , implicitAssertion : String = ""): String
84- fun decode (token : String , footer : PasetoFooter ? = null, implicitAssertion : String = ""): Token
84+ fun decode (token : String , footer : Footer ? = null, implicitAssertion : String = ""): Token
8585
8686 /* *
8787 * Decode the token's footer without verifying the token.
8888 *
89- * This is useful if the token footer contains data required to decode the token. Returns an [TaintedPasetoFooter ]
89+ * This is useful if the token footer contains data required to decode the token. Returns an [TaintedFooter ]
9090 * to prevent misuse as this footer should **never** be used when checking the footer during decoding.
9191 *
9292 * @param [token] paseto token to decode the footer of.
93- * @return [TaintedPasetoFooter ] with the decoded footer contents.
93+ * @return [TaintedFooter ] with the decoded footer contents.
9494 */
95- fun insecureGetFooter (token : String ): TaintedPasetoFooter ?
95+ fun insecureGetFooter (token : String ): TaintedFooter
9696}
9797
9898internal class LocalTokenService internal constructor(
9999 private val paseto : Paseto ,
100- private val keyProvider : () -> SymmetricKey ,
100+ private val keyProvider : (footer: TaintedFooter ) -> SymmetricKey ,
101101 private val rules : Rules ,
102102 private val footerOptions : FooterOptions ,
103103 private val json : Json = Json { explicitNulls = false },
@@ -112,20 +112,20 @@ internal class LocalTokenService internal constructor(
112112 val encodedFooter = json.encodeFooter(footerOptions, token.footer)
113113 return paseto.encrypt(
114114 m = encoded.toByteArray(Charsets .UTF_8 ),
115- key = keyProvider(),
116- footer = encodedFooter ? : " " ,
115+ key = keyProvider(token.footer.taint() ),
116+ footer = encodedFooter,
117117 implicitAssertion = implicitAssertion,
118118 )
119119 }
120120
121- override fun decode (token : String , footer : PasetoFooter ? , implicitAssertion : String ): Token {
121+ override fun decode (token : String , footer : Footer ? , implicitAssertion : String ): Token {
122122 if (implicitAssertion.isNotEmpty() && ! paseto.supportsImplicitAssertion) {
123123 throw ImplicitAssertionsNotSupportedException (paseto.version)
124124 }
125125
126126 val (encoded, footer) = paseto.decrypt(
127127 token = token,
128- key = keyProvider(),
128+ key = keyProvider(insecureGetFooter(token) ),
129129 footer = footer?.let { json.encodeFooter(footerOptions, it) },
130130 implicitAssertion = implicitAssertion,
131131 )
@@ -136,13 +136,13 @@ internal class LocalTokenService internal constructor(
136136 return decoded
137137 }
138138
139- override fun insecureGetFooter (token : String ): TaintedPasetoFooter ? =
139+ override fun insecureGetFooter (token : String ): TaintedFooter =
140140 json.decodeFooter(footerOptions, extractFooter(token)).taint()
141141}
142142
143143internal class PublicTokenService internal constructor(
144144 private val paseto : Paseto ,
145- private val keyProvider : () -> KeyPair ,
145+ private val keyProvider : (footer: TaintedFooter ) -> KeyPair ,
146146 private val rules : Rules ,
147147 private val footerOptions : FooterOptions ,
148148 private val json : Json = Json { explicitNulls = false },
@@ -156,27 +156,27 @@ internal class PublicTokenService internal constructor(
156156 rules.verifyAll(token, Rule .Mode .ENCODE )
157157 val encoded = json.encodeToString(PasetoTokenSerializer , token)
158158 val encodedFooter = json.encodeFooter(footerOptions, token.footer)
159- val keyPair = keyProvider()
159+ val keyPair = keyProvider(token.footer.taint() )
160160 if (keyPair.secretKey == null ) {
161161 throw CannotSignWithoutSecretKey ()
162162 }
163163 return paseto.sign(
164164 m = encoded.toByteArray(Charsets .UTF_8 ),
165165 secretKey = keyPair.secretKey,
166- footer = encodedFooter ? : " " ,
166+ footer = encodedFooter,
167167 implicitAssertion = implicitAssertion,
168168 )
169169 }
170170
171- override fun decode (token : String , footer : PasetoFooter ? , implicitAssertion : String ): Token {
171+ override fun decode (token : String , footer : Footer ? , implicitAssertion : String ): Token {
172172 // TODO expand service-test-vectors for v4 with implicit assertions
173173 if (implicitAssertion.isNotEmpty() && ! paseto.supportsImplicitAssertion) {
174174 throw ImplicitAssertionsNotSupportedException (paseto.version)
175175 }
176176
177177 val (encoded, footer) = paseto.verify(
178178 token = token,
179- publicKey = keyProvider().publicKey,
179+ publicKey = keyProvider(insecureGetFooter(token) ).publicKey,
180180 footer = footer?.let { json.encodeFooter(footerOptions, it) },
181181 implicitAssertion = implicitAssertion,
182182 )
@@ -187,6 +187,6 @@ internal class PublicTokenService internal constructor(
187187 return decoded
188188 }
189189
190- override fun insecureGetFooter (token : String ): TaintedPasetoFooter ? =
190+ override fun insecureGetFooter (token : String ): TaintedFooter =
191191 json.decodeFooter(footerOptions, extractFooter(token)).taint()
192192}
0 commit comments